题目链接:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4074

题目大意:有n头牛在环形跑道赛跑,最快的牛跑L圈时停止,每头牛速度恒定,问总共有多少次"crossing event“(一头牛从另一头后面超过它,简称CE)。

分析:因为速度恒定,所以真正的超越是不可能的,只可能是快的牛超过慢的牛刚好一整圈。于是问题变为快牛总共超过慢牛多少圈。

一个很自然的想法是把牛按速度从慢到快排序(或者说,把牛按跑的圈数从小到大排序),然后记录前面的牛跑的总圈数,也就是说,记牛i跑a[i]圈,那么牛i总共超过比它慢的牛a[i] * i - sum(i - 1)圈,其中牛下标从0开始,sum(i - 1)是前i只牛跑的总圈数。

可是问题来了:只有超过的整数圈数才真正计数,比如前3头牛分别跑1, 2, 3.5圈,实际牛2超过牛0两次,超过牛1一次,总共3次,但如果按3.5 * 2 - (1 + 2)算,就会超过4次。解决的办法是:先只考虑整数部分,并假设a[i]的小数部分小于前面所有牛的小数部分,这时牛i超过前面的牛总共((int)a[i] - 1) - sum(i - 1),其中sum(i - 1)是前i头牛圈数的整数部分求和,a[i] - 1是因为a[i]的小数部分小,故实际少超一圈(记住,这是假设)。那么这样子我们就少算一部分,也就是实际比a[i]的小数部分小的那些牛,应该再加上1。至此,问题就转变成了前i个小数部分中有几个比a[i]的小数部分小,也就是动态名次问题,用平衡树可以解决。

比较囧的是,一开始写的SBT居然超时了……一怒之下用树状数组写,把小数部分 * 1000000,然后当成整数处理,WA,改成2000000,AC。

还有一点比较坑,就是精度问题(处理实数总是会有这种问题),按上面所说,应该把a[i]的小数部分变为tmp = (a[i] - (int)a[i]) * 2000000,但由于精度问题,应该查找比tmp + 1小的数的总数。代码中查找tmp + 2,并插入tmp + 1,是因为树状数组下标从1开始,故把所有数加1。

#include #include #include #include #include #include  #include #include #include #include #include #include #include #include #include #include #define mp make_pair #define X first #define Y second #define MEMSET(a, b) memset(a, b, sizeof(a)) using namespace std; typedef unsigned int ui; typedef long long ll; typedef unsigned long long ull; typedef pairpii; typedef vectorvi; typedef vi::iterator vi_it; typedef mapmii; typedef priority_queuepqi; typedef priority_queue, greater> rpqi; typedef priority_queuepqp; typedef priority_queue, greater> rpqp; const int MAX_N = 100000 + 2; const int MAX_V = 2000000; const double EPS = 1.0e-8; int speed[MAX_N]; ll sum[MAX_V + 2]; inline int lowbit(int x) { return x & (-x); } void update(int p) { while (p <= MAX_V) { ++sum[p]; p += lowbit(p); } } ll query(int p) { ll ret = 0; while (p) { ret += sum[p]; p -= lowbit(p); } return ret; } int main(int argc, char *argv[]) { // freopen("D:\\in.txt", "r", stdin); int n, l, c; ll ans = 0; ll sum = 0; cin >> n >> l >> c; for (int i = 0; i < n; ++i) { scanf("%d", speed + i); } sort(speed, speed + n); for (int i = 0; i < n; ++i) { double cir = (double)l * speed[i] / speed[n - 1]; int tmp = (int)((cir - (int)cir) * 2000000); ans += ((int)cir - 1) * (ll)i - sum + query(tmp + 2); update(tmp + 1); sum += (int)cir; } printf("%I64d\n", ans); return 0; } 

TOJ 4074 Running Laps -- 树状数组相关推荐

  1. TOJ 4354 HDU 4262 Juggler / 树状数组

    Juggler 时间限制(普通/Java):1000MS/3000MS     运行内存限制:65536KByte   描述 As part of my magical juggling act, I ...

  2. JZOJ 3.10 1542——跑步(树状数组+模拟+排序/归并排序)

    题目描述 FJ觉得赛马很无聊,于是决定调查将赛牛作为一种运动的可能性.他安排了N(1 <= N <= 100,000)头奶牛来进行一个L圈的赛牛比赛,比赛在一个环形的长度为C的跑道上进行. ...

  3. Why Did the Cow Cross the Road III(树状数组)

    Why Did the Cow Cross the Road III 时间限制: 1 Sec  内存限制: 128 MB 提交: 65  解决: 28 [提交][状态][讨论版] 题目描述 The l ...

  4. 【转载】树状数组题目

    先提个注意点,由于Lowbit(0) = 0,这会导致x递增的那条路径发生死循环,所有当树状数组中可能出现0时,我们都全部加一,这样可以避免0带来的麻烦-- 简单:       POJ 2299 Ul ...

  5. 如此好的树状数组学习资料

    树状数组学习系列1 之 初步分析--czyuan原创 其实学树状数组说白了就是看那张图,那张树状数组和一般数组的关系的,看懂了基本就没问题了,推荐下面这个教程:http://www.topcoder. ...

  6. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

  7. Color the ball(HDU1556)树状数组

    每次对区间内气球进行一次染色,求n次操作后后所有气球染色次数. 树状数组,上下区间更新都可以,差别不大. 1.对于[x,y]区间,对第x-1位减1,第y位加1,之后向上统计 #include<b ...

  8. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

  9. Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)

    题意: 线段树做法 分析: 因为每次都是在当前位置的前缀区间查询最大值,所以可以直接用树状数组优化.比线段树快了12ms~ 代码: #include<cstdio> #include< ...

最新文章

  1. 程序员生存定律--编程的起点与可能的失足
  2. android地图路径绘制,android:利用svg的path路径+canvas 开发自定义地图控件
  3. [转] JavaScript中的属性:如何遍历属性
  4. URL转微信可识别的二维码
  5. 第四天的作业与答案,py直播
  6. 内核网络输出帧的处理
  7. 推荐系统系列教程之十五:一网打尽协同过滤、矩阵分解和线性模型
  8. Android input keyevent命令
  9. 关于引力波的一些疑问
  10. 玉米社:百度SEM竞价推广策略有哪些?
  11. ayit第十周训练g题
  12. 为什么php打开网页空白的_PHP网站打开空白的三个原因和对应的解决办法
  13. oracle 4043,oracle desc dba_data_files视图报ORA-4043错误小记
  14. iOS bounds备忘
  15. oracle获取当前时间
  16. 基于51单片机篮球计分系统
  17. 汉语编程的时代会到来吗?
  18. Win10笔记本扩展显示屏模糊处理办法
  19. BootLoader(U-Boot)启动过程记录
  20. appium+android各配置参数获取'platformName'、'platformVersion'、appActivity、deviceName、webdriver.Remote...

热门文章

  1. STM32串口用中断还是用轮询
  2. FLASH学习资料整理
  3. MapReduce调优方案
  4. 线路板基础知识详细解析
  5. Shared Project
  6. 买了个VR眼镜,体验一下元宇宙
  7. CentOS7 磁盘重新调整分配
  8. 计算机专业十六字口号,16字口号大全
  9. 特征选择,熵,条件熵,信息增益
  10. 微信小程序学习总结(4.wx:if按钮切换)