BZOJ 1176: [Balkan2007]Mokia CDQ

来源:互联网 发布:网络推广好处 编辑:程序博客网 时间:2024/05/18 02:53

1176: [Balkan2007]Mokia

Time Limit: 30 Sec  Memory Limit: 162 MB
Submit: 2592  Solved: 1161
[Submit][Status][Discuss]

Description

维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.

Input

第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小
接下来每行为一下三种输入之一(不包含引号):
"1 x y a"
"2 x1 y1 x2 y2"
"3"
输入1:你需要把(x,y)(第x行第y列)的格子权值增加a
输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出
输入3:表示输入结束

Output

对于每个输入2,输出一行,即输入2的答案

Sample Input

0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3

Sample Output

3
5

应该这才是BJ真正意义上的CDQ第一题了吧。。

裸三维偏序问题。。

再推荐一遍【教程】简易CDQ分治教程&学习笔记

重点:三元组(时间,横坐标,纵坐标)


#include<cmath>#include<ctime>#include<cstdio>#include<cstring>#include<cstdlib>#include<complex>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<bitset>#include<queue>#include<map>#include<set>using namespace std;typedef long long ll;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}void print(int x){if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}const int N=200100;struct P{int opt,x,y,pos;ll ans;}p[N];int W;inline bool cmp(int x,int y){return p[x].x==p[y].x?p[x].y==p[y].y?p[x].opt<p[y].opt:p[x].y<p[x].y:p[x].x<p[y].x;}ll bit[N*10];inline void modify(int x,int val){if(!x)return ;for(;x<=W;x+=(x&-x))bit[x]+=val;}inline ll query(int x){ll res=0;for(;x;x-=(x&-x))res+=bit[x];return res;}int tot;int a[N],tmp[N];void cdq(int l,int r){if(l==r)return ;int mid=(l+r)>>1;cdq(l,mid);cdq(mid+1,r);register int i=l,j=mid+1;while(j<=r){while(i<=mid&&p[a[i]].x<=p[a[j]].x){if(p[a[i]].opt==1)modify(p[a[i]].y,p[a[i]].ans);i++;}if(p[a[j]].opt>1)p[a[j]].ans+=query(p[a[j]].y);j++;}while(i>l){i--;if(p[a[i]].opt==1)modify(p[a[i]].y,-p[a[i]].ans);}i=l,j=mid+1;int top=l-1;while(j<=r||i<=mid){if(i>mid)tmp[++top]=a[j++];else if(j>r||p[a[i]].x<=p[a[j]].x)tmp[++top]=a[i++];else tmp[++top]=a[j++];}memcpy(a+l,tmp+l,sizeof(int)*(r-l+1));}int qnum;ll ans[N];int main(){ll S=read();W=read();register int opt=read(),x,y,x2,y2,val,i;while(opt^3){x=read();y=read();if(opt==1){val=read();p[++tot]=(P){1,x,y,0,val};}else{x2=read();y2=read();x--,y--;p[++tot]=(P){2,x2,y2,++qnum,S*(x2-x)*(y2-y)};p[++tot]=(P){2,x,y,qnum,0};p[++tot]=(P){3,x,y2,qnum,0};p[++tot]=(P){3,x2,y,qnum,0};}opt=read();}for(i=1;i<=tot;++i)a[i]=i;cdq(1,tot);for(i=1;i<=tot;++i)if(p[i].opt==2)ans[p[i].pos]+=p[i].ans;else if(p[i].opt==3)ans[p[i].pos]-=p[i].ans;for(i=1;i<=qnum;++i){print(ans[i]);puts("");}return 0;}/*0 41 2 3 32 1 1 3 31 2 2 22 2 2 3 4335*/