bzoj2683 简单题
来源:互联网 发布:apt get install java 编辑:程序博客网 时间:2024/06/09 17:39
Description
你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:
命令
参数限制
内容
1 x y A
1<=x,y<=N,A是正整数
将格子x,y里的数字加上A
2 x1 y1 x2 y2
1<=x1<= x2<=N
1<=y1<= y2<=N
输出x1 y1 x2 y2这个矩形内的数字和
3
无
终止程序
Input
输入文件第一行一个正整数N。
接下来每行一个操作。
Output
对于每个2操作,输出一个对应的答案。
Sample Input
4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
5
HINT
1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。
分析:
CDQ分治入门题
典型的三维偏序模型:
- 时间
- x坐标
- y坐标
网上很多题解都是把询问拆成了4个(二维前缀和)
实际上我们可以把询问拆成两个:
因为我们是按照时间顺序读入的
所以一开始时间这一维就已经有序了(已经消除了影响)
在CDQ分治的时候,我们先把左右区间按照x坐标排序(如果x坐标相同,修改就排到询问之前)
在左右区间各设置一个指针:t1,t2
从前往后扫,相当于按照x进行一次归并
但是我们并不是真的归并起来
为什么呢?因为我们之后要把树状数组清零,我们不能打乱左右区间的所属元素
这样方便我们之后从左区间找到修改操作并且消除影响(这样也能节省时间)
在处理的时候我们还是遵循这个原则:左区间修改,右区间查询
tip
在排序的时候注意数组下标:
sort(po+L,po+M+1,cmp); //[L,M]sort(po+M+1,po+R+1,cmp); //[M+1,R]
处理完询问后,不要忘了消除左区间修改的影响
这时候我们多设置了一个last变量
记录最后的一个修改操作进行到哪里
这样在消除影响的时候就可以节省时间了
(如果没有的话会T,毕竟sort也是挺费时的)
//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int N=500010;struct node{ int type,x,ya,yb,id,z;};node po[N<<1],q[N<<1];int t[N],n,m,tot=0,totx=0,ans[N];void add(int x,int z) {for (int i=x;i<=n;i+=(i&(-i))) t[i]+=z;}int ask(int x) {int ans=0;for (int i=x;i>0;i-=(i&(-i))) ans+=t[i];return ans;}int cmp(const node &a,const node &b){ if (a.x!=b.x) return a.x<b.x; else return a.type<b.type;}void CDQ(int L,int R){ if (L==R) return; int M=(L+R)>>1; CDQ(L,M); CDQ(M+1,R); sort(po+L,po+M+1,cmp); //并不打乱两部分 sort(po+M+1,po+R+1,cmp); int t1=L,t2=M+1,last=0; while (t2<=R) //注意循环结束的标示:因为我们只要处理完右区间的询问就行了,那些还在后面的修改没有任何意义(不会影响本次的询问处理) { while (t1<=M&&po[t1].type!=1) t1++; while (t2<=R&&po[t2].type==1) t2++; if (t1<=M&&po[t1].x<=po[t2].x) { add(po[t1].ya,po[t1].z); last=t1++; } else if (t2<=R) { if (po[t2].type==2) ans[po[t2].id]-=ask(po[t2].yb)-ask(po[t2].ya-1),t2++; else ans[po[t2].id]+=ask(po[t2].yb)-ask(po[t2].ya-1),t2++; } } for (int i=L;i<=last;i++) if (po[i].type==1) add(po[i].ya,-po[i].z);}int main(){ scanf("%d",&n); int xa,ya,xb,yb,opt,z; for (;;) { scanf("%d",&opt); if (opt==1) { scanf("%d%d%d",&xa,&ya,&z); tot++; po[tot].type=1; po[tot].x=xa; po[tot].ya=ya; po[tot].z=z; } else if (opt==2) { scanf("%d%d%d%d",&xa,&ya,&xb,&yb); tot++; totx++; po[tot].type=2; po[tot].x=min(xa,xb)-1; po[tot].ya=min(ya,yb); po[tot].yb=max(ya,yb); po[tot].id=totx; tot++; po[tot].type=3; po[tot].x=max(xa,xb); po[tot].ya=min(ya,yb); po[tot].yb=max(ya,yb); po[tot].id=totx; } else break; } CDQ(1,tot); for (int i=1;i<=totx;i++) printf("%d\n",ans[i]); return 0;}
阅读全文
0 0
- 【BZOJ2683】简单题
- bzoj2683: 简单题
- bzoj2683简单题
- bzoj2683 简单题
- BZOJ2683: 简单题
- BZOJ2683: 简单题 kdtree
- BZOJ2683简单题
- bzoj2683 简单题
- BZOJ2683: 简单题
- bzoj2683 简单题
- [BZOJ2683]=[BZOJ4066]简单题
- 【BZOJ2683】简单题【CDQ分治】
- BZOJ2683 简单题 题解&代码
- BZOJ2683 简单题 [KD-tree]
- [BZOJ1176] [Balkan2007]Mokia/[BZOJ2683] 简单题
- BZOJ2683 简单题(CDQ分治)
- [BZOJ2683]简单题(cdq分治)
- 【bzoj2683】简单题 CDQ分治+树状数组
- 第八周实践项目6 猴子选大王(数组版)
- 欢迎使用CSDN-markdown编辑器
- 第八周实践项目7 对称矩阵的压缩存储及基本运算
- caffe各层参数详解
- 在 LeanCloud 上模拟事务操作来实现支付功能
- bzoj2683 简单题
- HTML5-margin-top的塌陷问题
- docker 应用-1(安装以及基础命令)
- xshell和putty远程连接与秘钥认证
- 李飞飞官方宣布谷歌AI中国中心在北京成立,李佳加入(实录+视频))
- prometheus 警告
- 大咖丨交通运输部科学研究院:交通运输大数据的基础环境正日益成熟-清数•思享会
- HTML5--div的特点展示
- 第八周实践项目8 稀疏矩阵的三元组表示的实现及应用