http://acm.hdu.edu.cn/showproblem.php?pid=5700

这是这次百度之星初赛2B的第五题。省赛回来看了一下,有这样一个思路:对于所有的区间排序,按左值排序。

然后枚举区间左值lt,计算区间右值rt最大是多少,并且满足与至少k个区间相交。关键是解决与k个区间相交这个关系。首先区间左值大于lt的是不考虑的,因为这样相交区间的左值就不是lt了。也就是考虑区间左值小于等于lt的区间中,与rt区间至少有k个相交的区间。也就是在前面的条件下,计算是否有至少k个区间右值大于等于rt。

于是,依次枚举区间,将区间右值加入树状数组。二分rt的位置,判断query(rt, n)在树状数组中的和是否大于k即可。

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <cstring>
  6. #include <algorithm>
  7. #include <set>
  8. #include <map>
  9. #include <queue>
  10. #include <vector>
  11. #include <string>
  12. #define LL long long
  13.  
  14. using namespace std;
  15.  
  16. const int maxN = ;
  17. int n, k, m;
  18. LL s[maxN];
  19.  
  20. struct node
  21. {
  22. int lt, rt;
  23.  
  24. bool operator<(node x) const
  25. {
  26. if (lt != x.lt) return lt < x.lt;
  27. else return rt < x.rt;
  28. }
  29. }p[maxN];
  30.  
  31. int d[maxN];
  32.  
  33. int lowbit(int x)
  34. {
  35. return x&(-x);
  36. }
  37.  
  38. void add(int id,int pls)
  39. {
  40. while(id <= maxN)//id最大是maxN
  41. {
  42. d[id] += pls;
  43. id += lowbit(id);
  44. }
  45. }
  46.  
  47. int sum(int to)
  48. {
  49. int s = ;
  50. while(to > )
  51. {
  52. s = s + d[to];
  53. to -= lowbit(to);
  54. }
  55. return s;
  56. }
  57.  
  58. int query(int from, int to)
  59. {
  60. return sum(to) - sum(from-);
  61. }
  62.  
  63. void input()
  64. {
  65. int t;
  66. s[] = ;
  67. for (int i = ; i <= n; ++i)
  68. {
  69. scanf("%d", &t);
  70. s[i] = s[i-]+t;
  71. }
  72. }
  73.  
  74. int cal(int lt)
  75. {
  76. int rt = n, mid;
  77. while (lt+ < rt)
  78. {
  79. mid = (lt+rt)>>;
  80. if (query(mid, n) >= k) lt = mid;
  81. else rt = mid;
  82. }
  83. if (query(rt, n) >= k) return rt;
  84. else if (query(lt, n) >= k) return lt;
  85. else return -;
  86. }
  87.  
  88. void work()
  89. {
  90. for (int i = ; i < m; ++i)
  91. scanf("%d%d", &p[i].lt, &p[i].rt);
  92. sort(p, p+m);
  93. memset(d, , sizeof(d));
  94. LL ans = ;
  95. int to;
  96. for (int i = ; i < m; ++i)
  97. {
  98. add(p[i].rt, );
  99. to = cal(p[i].lt);
  100. if (to != -) ans = max(ans, s[to]-s[p[i].lt-]);
  101. }
  102. printf("%lld\n", ans);
  103. }
  104.  
  105. int main()
  106. {
  107. //freopen("test.in", "r", stdin);
  108. //freopen("test.out", "w", stdout);
  109. while (scanf("%d%d%d", &n, &k, &m) != EOF)
  110. {
  111. input();
  112. work();
  113. }
  114. return ;
  115. }

ACM学习历程—HDU5700 区间交(树状数组 && 前缀和 && 排序)的更多相关文章

  1. ACM学习历程—HDU4417 Super Mario(树状数组 && 离线)

    Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...

  2. 51nod_1199 树的先跟遍历+区间更新树状数组

    题目是中文,所以不讲题意 做法顺序如下: 使用先跟遍历,把整棵树平铺到一维平面中 使用自己整的区间更新树状数组模板进行相关操作. http://www.cnblogs.com/rikka/p/7359 ...

  3. 51nod 1081 子段求和(线段树 | 树状数组 | 前缀和)

    题目链接:子段求和 题意:n个数字序列,m次询问,每次询问从第p个开始L长度序列的子段和为多少. 题解:线段树区间求和 | 树状数组区间求和 线段树: #include <cstdio> ...

  4. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  5. 51Nod 1680 区间求和 树状数组

    题意: 给出一个长度为\(n\)的数列\(A_i\),定义\(f(k)\)为所有长度大于等于\(k\)的子区间中前\(k\)大数之和的和. 求\(\sum_{k=1}^{n}f(k) \; mod \ ...

  6. nyoj--108--士兵杀敌(一)(区间求和&&树状数组)

    士兵杀敌(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军现在想知 ...

  7. 区间操作---树状数组&&线段树

    涉及区间操作的一些套路必须要会呀 区间加减为了偷懒能不写线段树so我选择树状数组!! 但是区间乘除,最大值我想了想还是用线段树分块吧. 树状数组: 这里用网上的一张图: 这里灰色数组是原本的数组(a[ ...

  8. CSU - 1551 Longest Increasing Subsequence Again —— 线段树/树状数组 + 前缀和&后缀和

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1551 题意: 给出一段序列, 删除其中一段连续的子序列(或者不删), 使得剩下的序列 ...

  9. Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)

    题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和X ...

随机推荐

  1. H5新特性---新应用

    1.持久化本地存储 可以不通过第三方插件实现数据的本地存储 2.WebSocket 页面之间可以双向通信 3.服务器推送事件(SSE) 从Web服务器将消息推送给浏览器(在手机中常见) 例如: < ...

  2. 使用C语言扩展Python提供性能

    python底层是用c写的,c本身是一个非常底层的语言,所以它做某些事情的效率肯定会比上层语言高一些. 比如有些自动化测试用的python库,会对系统的UI进行一些捕获,点击之类的操作,这必然要用到c ...

  3. python标准库学习-ftplib

    源码: """An FTP client class and some helper functions. Based on RFC 959: File Transfer ...

  4. CocoaPods学习系列5——错误集锦

    这篇文章记录使用CocoaPods过程中遇到的一些错误. 1.error:include of non-modular header inside framework module 在自定义类库中,引 ...

  5. scala学习手记12 - 字段、方法和构造函数

    在上一节创建了一个scala类,如果没有更多的方法,scala类的定义还可以更简单一些,看一下下面这个CreditCard类的定义: class CreditCard(val number: Int, ...

  6. mysql 导入表数据中文乱码

    方法一: 先在命令行设置为utf8,再导入 1. use database_name; 2. set names utf8; (或其他需要的编码) 3. source example.sql (sql ...

  7. PHP中的定界符

    因为PHP是一个Web编程语言,在编程过程中难免会遇到用echo来输出大段的html和javascript脚本的情况,如果用传统的输出方法——按字符串输出的话,肯定要有大量的转义符来对字符串中的引号等 ...

  8. MSSQL旋转和反旋转的例子

    1.旋转 ;WITH CTE AS ( AS VAL UNION ALL UNION ALL UNION ALL UNION ALL UNION ALL UNION ALL UNION ALL ) S ...

  9. TCPL学习笔记:4-12以及4-13。关于使用递归的问题。

    4-12.写一个函数itoa,通过递归调用将整数转换成为字符串. #include <stdio.h> #include <stdlib.h> void Itoa(int nu ...

  10. Ubuntu源更新

    Ubuntu12.04的源在 /etc/apt/sources.list  中, 进入 /etc/apt/ 先进行备份 然后用根用户权限打开sources.list. sudo gedit /etc/ ...