题解:

感觉这题和别人的做法不一样。。。呵呵呵。。。调了一百年。。

设家坐标为(a,b),对于每个点(x,y),可以转化为|a-x|+|b-y|<=k

对于每个点,它的影响范围是一个菱形(也就是一个正方形啦。。),也就是一个图上有若干个正方形。

然后我就把这个坐标轴选择了45度。

好难画不画了,正交分解一下就可以了。

然后题目就转化成正方形各种交里的最大值。

正方形有x和y两个元素,但是很明显我们只能维护一个。。

所以我以x轴建立线段树,对于每个正方形按照y从小到大排序。

维护一个指针j,表示当前前j个正方形已经和现在在处理的第i个正方形没有交集。每次都要先把j更新(看看它是否能后移)。

然后我们在当前正方形的两端a[i].x~a[i].y这一段+a[i].d

每个点维护当前的和d以及该区间的最大值mx。每次做完之后,用t[1].mx更新答案。

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<ctime>
  6. #include<queue>
  7. #include<algorithm>
  8. using namespace std;
  9.  
  10. const int N=,INF=(int)1e9;
  11. int n,K,L,tl,ans;
  12. struct trnode{
  13. int l,r,lc,rc,d,mx,lazy;
  14. }t[*N];
  15. struct node{
  16. int x,y,d;
  17. }a[N];
  18.  
  19. bool cmp(node x,node y){return x.y<y.y;}
  20. int maxx(int x,int y){return x>y ? x:y;}
  21. int minn(int x,int y){return x<y ? x:y;}
  22.  
  23. int read()
  24. {
  25. int x=,f=; char ch=getchar();
  26. while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();}
  27. while(ch>=''&&ch<=''){x=x*+ch-''; ch=getchar();}
  28. return x*f;
  29. }
  30.  
  31. int bt(int l,int r)
  32. {
  33. int x=++tl;
  34. t[x].l=l;t[x].r=r;
  35. t[x].lc=t[x].rc=;
  36. t[x].mx=;t[x].d=;
  37. t[x].lazy=;
  38. if(l<r)
  39. {
  40. int mid=(l+r)/;
  41. t[x].lc=bt(l,mid);
  42. t[x].rc=bt(mid+,r);
  43. }
  44. return x;
  45. }
  46.  
  47. void pd(int x)
  48. {
  49. if(t[x].lazy==) return ;
  50. int d=t[x].lazy,lc=t[x].lc,rc=t[x].rc;
  51. t[x].lazy=;
  52. t[x].d+=d;
  53. t[x].mx+=d;
  54. if(lc) t[lc].lazy+=d;
  55. if(rc) t[rc].lazy+=d;
  56. }
  57.  
  58. void change(int x,int l,int r,int d)
  59. {
  60. pd(x);
  61. if(t[x].l==l && t[x].r==r)
  62. {
  63. t[x].lazy+=d;
  64. pd(x);
  65. return ;
  66. }
  67. int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/;
  68. if(r<=mid) change(lc,l,r,d);
  69. else if(l>mid) change(rc,l,r,d);
  70. else
  71. {
  72. change(lc,l,mid,d);
  73. change(rc,mid+,r,d);
  74. }
  75. pd(x);pd(lc);pd(rc);
  76. t[x].mx=maxx(t[lc].mx,t[rc].mx);
  77. }
  78.  
  79. int main()
  80. {
  81. // freopen("a.in","r",stdin);
  82. // freopen("me.out","w",stdout);
  83. freopen("lazy.in","r",stdin);
  84. freopen("lazy.out","w",stdout);
  85. n=read();K=read();
  86. // scanf("%d%d",&n,&K);
  87. int x,y,tx,ty,nx=INF,ny=INF,mx=;tl=;L=*K;
  88. for(int i=;i<=n;i++)
  89. {
  90. a[i].d=read();x=read();y=read();
  91. // scanf("%d%d%d",&a[i].d,&x,&y);
  92. tx=x,ty=y+K;
  93. a[i].x=tx-ty;
  94. a[i].y=tx+ty;
  95.  
  96. nx=minn(nx,a[i].x);
  97. ny=minn(ny,a[i].y);
  98. }
  99. for(int i=;i<=n;i++)
  100. {
  101. a[i].x-=nx-;
  102. a[i].y-=ny-;
  103. mx=maxx(mx,a[i].x);
  104. }
  105. mx+=;ans=;
  106. sort(a+,a++n,cmp);
  107. bt(,mx);
  108. int j=;
  109. change(,a[].x,minn(mx,a[].x+L),a[].d);
  110. ans=maxx(ans,t[].mx);
  111. for(int i=;i<=n;i++)
  112. {
  113. while(j<i && a[i].y-L>a[j].y)
  114. {
  115. change(,a[j].x,minn(mx,a[j].x+L),-a[j].d);
  116. ans=maxx(ans,t[].mx);
  117. j++;
  118. }
  119. change(,a[i].x,minn(mx,a[i].x+L),a[i].d);
  120. ans=maxx(ans,t[].mx);
  121. }
  122. printf("%d\n",ans);
  123. return ;
  124. }

【bzoj3476-懒惰的奶牛】线段树的更多相关文章

  1. Codeforces 444C 线段树 懒惰标记

    前天晚上的CF比赛div2的E题,很明显一个线段树,当时还在犹豫复杂度的问题,因为他是区间修改和区间查询,肯定是要用到懒惰标记. 然后昨天真的是给这道题跪了,写了好久好久,...我本来是写了个add标 ...

  2. D - Mayor's posters(线段树+离散化)

    题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...

  3. 【HDU 4614】Vases and Flowers(线段树区间更新懒惰标记)

    题目0到n-1的花瓶,操作1在下标a开始插b朵花,输出始末下标.操作2清空[a,b]的花瓶,求清除的花的数量.线段树懒惰标记来更新区间.操作1,先查询0到a-1有num个空瓶子,然后用线段树的性质,或 ...

  4. 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  5. 【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

  6. poj3468 线段树的懒惰标记

    题目链接:poj3468 题意:给定一段数组,有两种操作,一种是给某段区间加c,另一种是查询一段区间的和 思路:暴力的方法是每次都给这段区间的点加c,查询也遍历一遍区间,复杂度是n*n,肯定过不去,另 ...

  7. HDU 4107 Gangster(线段树 特殊懒惰标记)

    两种做法. 第一种:标记区间最大值和最小值,若区间最小值>=P,则本区间+2c,若区间最大值<P,则本区间+c.非常简单的区间更新. 最后发一点牢骚:最后query查一遍就行,我这个2B竟 ...

  8. POJ 3468 线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  9. Transformation HDU - 4578(线段树——懒惰标记的妙用)

    Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...

随机推荐

  1. MHDD工具使用简写

    检查硬盘,建议接主板一口,DOS工具箱输入mhdd回车进入界面 输入硬盘接口号(这里不固定) 按F4是进行硬盘扫描,按两次就开始,按方向键进行快进 Mhdd界面输入 erase命令:擦除指定扇区范围内 ...

  2. 【bzoj5107】[CodePlus2017]找爸爸 dp

    题目描述 给出两个基因串,你需要在其中插入任意个空格,使得两个串长度相同.如果两个串的某同一位置都是字母则获得某给定收益,对于每个串的每个长度为k的连续空格段要付出a(k-1)+b的损失.求最大净收益 ...

  3. CF986B Petr and Permutations

    题意翻译 Petr要打乱排列.他首先有一个从 111 到 nnn 的顺序排列,然后进行 3n3n3n 次操作,每次选两个数并交换它们. Alex也要打乱排列.他与Petr唯一的不同是他进行 7n+17 ...

  4. Python程序性能分析模块----------cProfile

    cProfile分析器可以用来计算程序整个运行时间,还可以单独计算每个函数运行时间,并且告诉你这个函数被调用多少次 def foo(): pass import cProfile cProfile.r ...

  5. 进程池-限制同一时间在CPU上运行的进程数

    if __name__=='__main__' :  为了区分你是主动执行这个脚本,还是从别的地方把它当做一个模块去调用. 如果是主动执行,则执行.如果是调用的,则不执行主体. 1. 串行:切记切记: ...

  6. UOJ228:基础数据结构练习题——题解

    http://uoj.ac/problem/228 参考:https://www.cnblogs.com/ljh2000-jump/p/6357583.html 考虑当整个区间的最大值开方==最小值开 ...

  7. [bzoj] 2049 洞穴勘探 || LCT

    原题 这是一道LCT的板子题. 至于LCT--link cut tree,也叫动态树,用splay实现动态连边的树. 预备知识: 实边:一个非叶节点,向它的儿子中的一个连一条特殊的边,称为实边;该非叶 ...

  8. cgroups 命令集

    cgroups 命令集 最后介绍,功能最为强大的控制组(cgroups)的用法.cgroups 是 Linux 内核提供的一种机制,利用它可以指定一组进程的资源分配. 具体来说,使用 cgroups, ...

  9. STL之六:map/multimap用法详解

    转载于:http://blog.csdn.net/longshengguoji/article/details/8547007 map/multimap 使用map/multimap之前要加入头文件# ...

  10. POJ3468:A Simple Problem with Integers(线段树模板)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 149972 ...