題目
維護一個W*W的矩陣,初始值均爲S.每次操做能夠增長某格子的權值,或詢問某子矩陣的總權值.修改操做數M<=160000,詢問數Q<=10000,W<=2000000.spa
維護一個W*W的矩陣,初始值均爲S.每次操做能夠增長某格子的權值,或詢問某子矩陣的總權值.修改操做數M<=160000,詢問數Q<=10000,W<=2000000.spa
第一行兩個整數,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:表示輸入結束code
對於每一個輸入2,輸出一行,即輸入2的答案blog
0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
3
5
#include<cstdio> #include<algorithm> using namespace std; #define lowbit(x) ((x)&-(x)) #define ff() for(int i=l;i<=r;i++) struct data{int v,x,y,d,f,pos; bool operator <(const data& w)const{ if(x!=w.x)return x<w.x;if(y!=w.y)return y<w.y; return pos<w.pos;} }a[200005],tmp[200005]; int s,w,t[2000005],cnt,ans[200005]; int I(){int x=0,f=1;char c=getchar(); for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1; for(;'0'<=c&&c<='9';c=getchar())x=(x<<3)+(x<<1)+(c^48);return x*f;} inline void add(int y,int x){for(int i=y;i<=w;i+=lowbit(i)) t[i]+=x;} inline int query(int y){int ret=0; for(int i=y;i;i-=lowbit(i)) ret+=t[i]; return ret;} void CDQ(int l,int r){if(l==r)return; int mid=(l+r)>>1,t1=l-1,t2=mid; ff(){if(a[i].v<=mid&&!a[i].pos)add(a[i].y,a[i].d); if(a[i].v>mid&&a[i].pos)ans[a[i].pos]+=query(a[i].y)*a[i].f;} ff()if(a[i].v<=mid&&!a[i].pos)add(a[i].y,-a[i].d); ff()a[i].v<=mid?tmp[++t1]=a[i]:tmp[++t2]=a[i]; ff()a[i]=tmp[i];CDQ(l,mid);CDQ(mid+1,r);} int main(){s=I();w=I();int t,x,y,d,x1,x2,y1,y2; while(1){t=I(); if(t==1)x=I(),y=I(),d=I(),a[++cnt]=(data){cnt,x,y,d,1,0}; else if(t==2)x1=I(),y1=I(),x2=I(),y2=I(),++ans[0], a[++cnt]=(data){cnt,x1-1,y1-1,0,1,ans[0]}, a[++cnt]=(data){cnt,x2,y2,0,1,ans[0]}, a[++cnt]=(data){cnt,x1-1,y2,0,-1,ans[0]}, a[++cnt]=(data){cnt,x2,y1-1,0,-1,ans[0]}; else break;}sort(a+1,a+1+cnt);CDQ(1,cnt); for(int i=1;i<=ans[0];i++)printf("%d\n",ans[i]); return 0;}