★★★☆
输入文件:locust.in 输出文件:locust.out 简单对比
时间限制:2 s 内存限制:128 MB

DESCRIPTION
C国国土辽阔,地大物博……但是最近却在闹蝗灾…..
我们可以把C国国土当成一个W×W的矩阵,你会收到一些诸如(X,Y,Z)的信息,代表(X,Y)这个点增多了
Z只蝗虫,而由于C国政府机关比较臃肿,为了批复消灭蝗虫的请求需要询问一大堆的问题……每个询问形如
(X1,Y1,X2,Y2),询问在(X1,Y1,X2,Y2)范围内有多少蝗虫(请注意询问不会改变区域内的蝗虫数),
你作为一个C国的程序员,需要编一个程序快速的回答所有的询问。

NOTICE
C国一开始没有蝗虫。

INPUT
输入文件的第一行包括一个整数W,代表C国国土的大小。第二行有一个整数N,表示事件数。接下来有N行表示N个事件,以(1 X Y Z)的形式或(2,X1,Y1,X2,Y2)的形式给出,分别代表蝗虫的增加和询问。

OUTPUT
对于每个询问输出一个整数表示需要的结果。

SAMPLE INPUT
locust.in
5
8
2 4 1 4 2
1 3 1 8
1 4 4 4
2 1 3 4 4
1 1 5 1
1 4 4 5
2 2 2 5 4
2 3 2 4 4

SAMPLE OUTPUT
locust.out
0
4
9
9

数据范围:
10%的数据满足W<=100,N<=100;
30%的数据满足W<=2000,N<=5000;
50%的数据满足W<=100000,N<=50000;
100%的数据满足W<=500000,N<=200000,每次蝗虫增加数不超过1000;

时间限制:
2s

分析:
CDQ分治
(听说是一个叫CDQ的前辈(♀)发明的)

学习算法的开端都是趁热打铁,抄袭代码
这是一道CDQ的入门题

题目已经简化了
大地上初始时没有蝗虫

Q:那要是有怎么办呢
A:那就当做是修改操作处理了

CDQ的一部分模型都是三维偏序
实际上就是每个元素都有三个限制因素
要依照这三个限制操作

那这道题的三个限制在哪呢

首先这是一道二维修改查询的题
提到二维区间的和,立刻想到了二维前缀和
每一个矩阵都可以由四个前缀矩阵计算出来,
那么对于每一个前缀矩阵,只有位于ta左下角的修改会对ta产生影响
(我们默认左下角为坐标原点)
而修改和查询又有一定的时间顺序
这样我们的三个限制就出来了:
1.时间
2.x坐标小于等于当前点
3.y坐标小于等于当前点

我们需要定义一个solve函数
solve(l,r)可以做到处理完所有l到r的操作
我们先按输入的时间形成一个序列

我是在只停留在理论的层次上做这道题的
一开始还在想,不是要按照输入时间排序吗,
dalao的程序为什么没有sort,
(傻吗,输入的时候顺序存储不就已经排好序了吗)
。。。sto orz

那我们在时间排序的基础上分治solve
用左区间修改右区间

先把左区间中的所有修改

和右区间的所有询问复制到一个数组里

复制出来的修改是一定会影响这些询问的

按x排序,如果x相同,插入在询问前
之后就是处理操作了

因为我们按照x排序了,所以先插入的必定会对后面前缀和有影响
那我们要怎么处理y这个限制呢

我们开一个纵向的树状数组,

维护y方向上的修改,这就相当于把整个y轴向右扫描
遇到询问就进行相应的处理

这里要注意我们把每个询问拆成了两个

毕竟确定一个询问需要两个坐标,如图
那ta的意义何在呢
之所以把询问拆成两个,是为了在排序的时候,
第一个分身排在前,第二个分身排在后,
*如果遇到了第一个分身:
就在当前的询问中减去该询问不包含的区间值
*遇到第二个分身的时候:
在询问中加上这一部分的区间值

最后恢复树状数组的初始状态
继续递归下去

tip

solve的时候边界是l和r
不要一个手滑写成1和n(就像某zz)

cogs真心难用。。。

这里写代码片
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>using namespace std;const int N=200005;
int w,n,ans[N];
struct node{int bh,t,xa,ya,xb,yb,z;  //谨慎使用y1
};
node q[N],c[N<<1];
int cc,tree[500005];int cmp(const node &a,const node &b)
{if (a.xa==b.xa) return a.t<b.t;   //插入排在询问前 return a.xa<b.xa;
}void add(int bh,int a)
{for (int i=bh;i<=w;i+=(i&(-i)))tree[i]+=a;
}int ask(int bh)
{int ans=0;for (int i=bh;i>0;i-=(i&(-i)))ans+=tree[i];return ans;
}void solve(int l,int r)
{if (l==r) return;int mid=(l+r)>>1;cc=0;for (int i=l;i<=mid;i++)if (q[i].t==0)c[cc++]=q[i];for (int i=mid+1;i<=r;i++)if (q[i].t){c[cc++]=q[i];c[cc++]=q[i];c[cc-2].xa--;c[cc-1].xa=c[cc-1].xb;c[cc-1].t=2;}sort(c,c+cc,cmp);for (int i=0;i<cc;i++){if (c[i].t==0)  //插入 add(c[i].ya,c[i].z);else if (c[i].t==1)ans[c[i].bh]-=ask(c[i].yb)-ask(c[i].ya-1);elseans[c[i].bh]+=ask(c[i].yb)-ask(c[i].ya-1);}for (int i=0;i<cc;i++)if (c[i].t==0)add(c[i].ya,-c[i].z);solve(l,mid);solve(mid+1,r);
}int main()
{freopen("locust.in","r",stdin);freopen("locust.out","w",stdout);scanf("%d%d",&w,&n);for (int i=1;i<=n;i++){int x,y,xx,yy;q[i].bh=i;scanf("%d",&q[i].t);  q[i].t--;if (q[i].t==0)  //插入 {scanf("%d%d%d",&q[i].xa,&q[i].ya,&q[i].z);}else  //查询 {scanf("%d%d%d%d",&x,&y,&xx,&yy);q[i].xa=min(x,xx);q[i].xb=max(x,xx);q[i].ya=min(y,yy);q[i].yb=max(y,yy);}}solve(1,n);for (int i=1;i<=n;i++)if (q[i].t)printf("%d\n",ans[i]);return 0;
}

转载于:https://www.cnblogs.com/wutongtong3117/p/7673423.html

cogs577. 蝗灾(CDQ)相关推荐

  1. [bzoj] 1176 Mokia || CDQ分治

    原题 给出W×W的矩阵(S没有用,题目有误),给出无限次操作,每次操作的含义为: 输入1:你需要把(x,y)(第x行第y列)的格子权值增加a 输入2:你需要求出以左下角为(x1,y1),右上角为(x2 ...

  2. 【BZOJ-3456】城市规划 CDQ分治 + NTT

    题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=3456 Solution 这个问题可以考虑dp,利用补集思想 N个点的简单图总数量为$2^{ ...

  3. BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )

    考虑cdq分治, 对于[l, r)递归[l, m), [m, r); 然后计算[l, m)的操作对[m, r)中询问的影响就可以了. 具体就是差分答案+排序+离散化然后树状数组维护.操作数为M的话时间 ...

  4. bzoj2961 共点圆 (CDQ分治, 凸包)

    /* 可以发现可行的圆心相对于我们要查询的点是在一个半平面上, 然后我们要做的就是动态维护凸壳然后用这个半平面去切它 看看是否是在合法的那一面然后cdq分治就可以了代码基本是抄的,*/#include ...

  5. 洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)

    题面 传送门 题解 题目转化一下就是所有点都在直线\(Ax+By-C=0\)的同一侧,也就可以看做所有点代入\(Ax+By-C\)之后的值符号相同,我们只要维护每一个点代入直线之后的最大值和最小值,看 ...

  6. 【BZOJ3963】[WF2011]MachineWorks cdq分治+斜率优化

    [BZOJ3963][WF2011]MachineWorks Description 你是任意性复杂机器公司(Arbitrarily Complex Machines, ACM)的经理,公司使用更加先 ...

  7. CDQ分治 + 树状数组 ---- C. Goodbye Souvenir(三维偏序+思维)

    题目链接 题目大意: 给定长度为nnn的数组, 定义数字XXX在[l,r][l,r][l,r]内的值为数字XXX在[l,r][l,r][l,r]内最后一次出现位置的下标减去第一次出现位置的下标 给定m ...

  8. 中国治理蝗灾是生物防治的成就,根本不是靠鸡靠鸭靠吃货换来的!

    近一段时间来,沙漠蝗虫全球肆虐,搞得人心惶惶.东非人民早就在和蝗虫进行紧张的肉搏战事了,乌干达政府宣布派出超过2000名军队人员来应对蝗灾,巴国空军更是出动149架战机要跟蝗虫开战等等. 正所谓居安思 ...

  9. [学习笔记]CDQ分治

    分治,考虑前一半对后一半的影响. (和一般分治不太相同的思想是,一般分治不分谁对谁的影响,跨mid的都要统计.(全局变量统计) 而CDQ貌似要落脚到前一半对后一半的影响上,也就是贡献在后一半统计,由前 ...

最新文章

  1. 什么是高层主管支持系统?
  2. 畅捷通携手易后台,专注小微企业财税服务
  3. STM32F10x_StdPeriph_Lib_V3.5.0库时钟分析及如何配置
  4. Oracle经验集锦
  5. 如何在vue里面正确的引用 jquery 和 第三方插件
  6. 用c语言实现对n个进程采用“短进程优先”算法的进程调度_为什么Linux CFS调度器没有带来惊艳的碾压效果?...
  7. SpringBoot高级-消息-RabbitMQ安装测试
  8. html loader 路径,Webpack html-loader提取链接和脚本
  9. Python使用超高效算法查找所有类似123-45-67+89=100的组合
  10. NYOJ题目170网络的可靠性
  11. 实现教科书图7.33的程序(另加孤立顶点台北)(两城市之间的最短路径模拟)
  12. 未来手机、电脑和网络将整合为一块
  13. 雷蛇灯光配置文件_突破极限!Razer雷蛇发布高性能V2版炼狱蝰蛇和巴塞利斯蛇...
  14. java的流套接_Java是什么原因导致网络套接字的流结束?
  15. 视频传输协议详解(RTMP、RTSP、HLS)
  16. 4款U盘操作系统推荐
  17. php跟安卓交互,android客户端跟php服务简单交互
  18. 10个好用的免费图片网站,绝对能在2021年设计上好帮手
  19. java entries_Enumerationlt;? extends ZipEntrygt; entries()_学习Java Zip|WIKI教程
  20. 朴素贝叶斯详解及中文舆情分析(附代码实践)

热门文章

  1. 【认证课程】NP理论复习之opsf(二)
  2. Android Day05-网络编程之文件下载之多线程断点续传技术
  3. Netflix工程总监眼中的分类算法:深度学习优先级最低
  4. 我是这么给娃娃取名的(使用 node.js )
  5. 如何在Ubuntu下面识别Galaxy Nexus设备
  6. python爬虫之 ---------------- 正则表达式(1)
  7. ubuntu安装mysql没反应_Ubuntu安装mysql三种安装方式
  8. word2010赠送_我们将赠送两台LulzBot 3D打印机
  9. SVG基础知识 Adobe Illustrator绘制SVG
  10. Bootstrap3 滚动监听插件的方法