HYSBZ-1176 Mokia

題目

維護一個W*W的矩陣,初始值均爲S.每次操做能夠增長某格子的權值,或詢問某子矩陣的總權值.修改操做數M<=160000,詢問數Q<=10000,W<=2000000.spa

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:表示輸入結束code

Output

對於每一個輸入2,輸出一行,即輸入2的答案blog

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

代碼

#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;}
相關文章
相關標籤/搜索