直接贪心,我们把线段按照右端点从小到大排序,然后一个个尝试插入即可。。。

来证明贪心的正确性:

不妨设贪心得到的答案集合为$S$,最优解的答案集合为$T$

若$S$不是最优解,那么$S \not= T$,不妨设按照右端点排序后,第一个不同的位置为$i$

则$S_i \not= T_i$,分情况讨论:

(1)$S_i$的左端点在$T_i$的右端点后,由于贪心的步骤这是不可能的

(2)$S_i$的右端点在$T_i$的右端点之前:

(2.1)$S_i$的右端点在$T_i$的左端点之前,即$S_i$、$T_i$不相交,我们发现存在$S' = \{S_1, S_2, ..., S_i\} \cup \{T_i, T_{i + 1}, ..., T_n\}$,且$|S'| = |T| + 1$,矛盾

(2.2)$S_i$的右端点在$T_i$的左端点之后,即$S_i$、$T_i$相交,我们直接令$S' = T - \{T_i\} + \{S_i\}$,于是有$|S'| = |T|$,即$S'$也是最优解

故可以证明贪心的正确性

于是每次模拟的时候利用线段树即可,时间复杂度$O(mlogm + mlogn)$

  1. /**************************************************************
  2. Problem: 1828
  3. User: rausen
  4. Language: C++
  5. Result: Accepted
  6. Time:772 ms
  7. Memory:5708 kb
  8. ****************************************************************/
  9.  
  10. #include <cstdio>
  11. #include <algorithm>
  12.  
  13. using namespace std;
  14. const int N = 1e5 + ;
  15. const int M = 1e5 + ;
  16. const int inf = 1e9;
  17.  
  18. int read();
  19.  
  20. struct data {
  21. int l, r;
  22.  
  23. inline void get() {
  24. l = read(), r = read();
  25. }
  26. inline bool operator < (const data &d) const {
  27. return r < d.r;
  28. }
  29. } a[M];
  30.  
  31. struct seg {
  32. seg *ls, *rs;
  33. int mn, tag;
  34.  
  35. #define Len (1 << 16)
  36. inline void* operator new(size_t) {
  37. static seg *mempool, *c;
  38. if (mempool == c)
  39. mempool = (c = new seg[Len]) + Len;
  40. c -> ls = c -> rs = NULL, c -> mn = c -> tag = ;
  41. return c++;
  42. }
  43. #undef Len
  44.  
  45. inline void update() {
  46. mn = min(ls -> mn, rs -> mn);
  47. }
  48. inline void push() {
  49. ls -> tag += tag, rs -> tag += tag;
  50. ls -> mn -= tag, rs -> mn -= tag;
  51. tag = ;
  52. }
  53.  
  54. #define mid (l + r >> 1)
  55. void build(int l, int r) {
  56. if (l == r) {
  57. mn = read();
  58. return;
  59. }
  60. (ls = new()seg) -> build(l, mid), (rs = new()seg) -> build(mid + , r);
  61. update();
  62. }
  63.  
  64. void modify(int l, int r, int L, int R) {
  65. if (L <= l && r <= R) {
  66. ++tag, --mn;
  67. return;
  68. }
  69. push();
  70. if (L <= mid) ls -> modify(l, mid, L, R);
  71. if (mid < R) rs -> modify(mid + , r, L, R);
  72. update();
  73. }
  74.  
  75. int query(int l, int r, int L, int R) {
  76. if (L <= l && r <= R) return mn;
  77. push();
  78. int res = inf;
  79. if (L <= mid) res = min(res, ls -> query(l, mid, L, R));
  80. if (mid < R) res = min(res, rs -> query(mid + , r, L, R));
  81. update();
  82. return res;
  83. }
  84. #undef mid
  85. } *T;
  86.  
  87. int n, m, ans;
  88.  
  89. int main() {
  90. int i;
  91. n = read(), m = read();
  92. (T = new()seg) -> build(, n);
  93. for (i = ; i <= m; ++i) a[i].get();
  94. sort(a + , a + m + );
  95. for (i = ; i <= m; ++i)
  96. if (T -> query(, n, a[i].l, a[i].r))
  97. T -> modify(, n, a[i].l, a[i].r), ++ans;
  98. printf("%d\n", ans);
  99. return ;
  100. }
  101.  
  102. inline int read() {
  103. static int x;
  104. static char ch;
  105. x = , ch = getchar();
  106. while (ch < '' || '' < ch)
  107. ch = getchar();
  108. while ('' <= ch && ch <= '') {
  109. x = x * + ch - '';
  110. ch = getchar();
  111. }
  112. return x;
  113. }

BZOJ1828 [Usaco2010 Mar]balloc 农场分配的更多相关文章

  1. BZOJ_1828_[Usaco2010 Mar]balloc 农场分配_线段树

    BZOJ_1828_[Usaco2010 Mar]balloc 农场分配_线段树 Description Input 第1行:两个用空格隔开的整数:N和M * 第2行到N+1行:第i+1行表示一个整数 ...

  2. BZOJ 1828: [Usaco2010 Mar]balloc 农场分配

    Description Input 第1行:两个用空格隔开的整数:N和M * 第2行到N+1行:第i+1行表示一个整数C_i * 第N+2到N+M+1行: 第i+N+1行表示2个整数 A_i和B_i ...

  3. 【BZOJ】1828: [Usaco2010 Mar]balloc 农场分配(经典贪心)

    [算法]贪心+线段树 [题意]给定n个数字ci,m个区间[a,b](1<=a,b<=10^5),每个位置最多被ci个区间覆盖,求最多选择多少区间. 附加退化问题:全部ci=1,即求最多的不 ...

  4. BZOJ 1828 [Usaco2010 Mar]balloc 农场分配(贪心+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1828 [题目大意] 现在有一些线段[l,r]的需求需要满足,i位置最多允许a[i]条线 ...

  5. bzoj 1828: [Usaco2010 Mar]balloc 农场分配【贪心+线段树】

    长得挺唬人的贪心,按照右端点排序,用最小值线段树的询问判断当前牛是否能放进去,能的话更新线段树,ans++ 来自https://www.cnblogs.com/rausen/p/4529245.htm ...

  6. [Usaco2010 Mar]gather 奶牛大集会

    [Usaco2010 Mar]gather 奶牛大集会 题目 Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会.每个奶牛居住在 ...

  7. 【BZOJ1827】[Usaco2010 Mar]gather 奶牛大集会 树形DP

    [BZOJ][Usaco2010 Mar]gather 奶牛大集会 Description Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来 ...

  8. BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP

    [Usaco2010 Mar]gather 奶牛大集会 Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会.每个奶牛居住在 N(1 ...

  9. 【树形DP/搜索】BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会

    1827: [Usaco2010 Mar]gather 奶牛大集会 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 793  Solved: 354[Sub ...

随机推荐

  1. 我的CSS布局之旅--持续更新

    虽然我也接触前端一年之久了,但是无奈从切图布局下来的经验还真是很不足,因为之前比赛或者是做小项目时全部都是自己负责设计,所以都是编写边设计,哎呀,也是醉了:或者是有模板,然后从人家上面扒拉下来的,真的 ...

  2. session的销毁

    删除某个session标志: session.removeAttribute("sessionUserName");移除用户,但session不变,下次登陆的时候看到的sessio ...

  3. laravel框架总结(十三) -- redis使用

    一切的前提都是已经安装好了redis服务器,并且能启动(我只总结了mac的安装方法:传送门) 我自己使用的是mac系统,有个教程可以参考下,传送门: 1.安装PHP PRedis 1>PRedi ...

  4. static变量引起的问题,List数据覆盖

    出现的问题:Listt加载数据时,后面加载的数据会覆盖前面的数据,把后面的数据变得和前面一样 原因:因为刚开始把添加的数据写成了静态变量,所以一个改了以后所有都改了 解决方法:把数据设成普通属性,非静 ...

  5. 手势(UIGestureRecognizer)

    通过继承 UIGestureRecognizer 类,实现自定义手势(手势识别器类). PS:自定义手势时,需要 #import <UIKit/UIGestureRecognizerSubcla ...

  6. SQL知识整理三:变量、全局变量、视图、事务、异常

           变量 1.局部变量的声明(一个@) declare @n int   --声明变量关键字为declare 然后@加变量名 后面是变量类型 declare @s varchar(36) 2 ...

  7. 【BZOJ】3436: 小K的农场

    3436: 小K的农场 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 938  Solved: 417[Submit][Status][Discuss ...

  8. validate插件深入学习-01 小白从看透一个插件开始

    没有编程基础的的我,即使看了一遍jq文档也不知道怎么写程序,一个新的插件看了也不知道怎么用. 总是想做自己会的,自己不会的永远不去触碰,就永远不会. 都说编程这东西,很多都有很像的地方了,一个语言学通 ...

  9. 图片懒加载--判断div ul中的li是否已经滑动到可视区域里

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  10. iscroll 下拉刷新功能

    版本号:iscroll4.2.5.js iscroll 版本很有关系  在线: demo链接   有出现白屏的bug,将iscroll版本改成iscroll4.2.5就可以了 html <!DO ...