Bzoj1176 [Balkan2007]Mokia

Time Limit: 30 Sec  Memory Limit: 162 MB
Submit: 2000  Solved: 890

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

HINT

保证答案不会超过int范围

Source

CDQ分治

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<algorithm>
 6 #define LL long long
 7 using namespace std;
 8 const int mxn=2000100;
 9 inline int read(){
10     int sum=0,flag=1;char ch=getchar();
11     while(ch!='-'&&(ch>'9'||ch<'0'))ch=getchar();
12     if(ch=='-'){flag=-1;ch=getchar();}
13     while(ch<='9'&&ch>='0'){sum=sum*10+ch-'0';ch=getchar();}
14     return sum*flag;
15 }
16 int n;
17 int t[mxn];
18 struct opt{
19     int flag,ti;int x,y,a;int id;
20 }a[mxn];
21 int cnt=0,ict=0;
22 LL ans[mxn];
23 int cmp(opt a,opt b){
24     return (a.x<b.x || (a.x==b.x && a.ti<b.ti));
25 }
26 inline void add(int x,int v){
27     while(x<=n){t[x]+=v;x+=x&-x;}
28 }
29 inline int ask(int x){
30     int res=0;
31     while(x){res+=t[x];x-=x&-x;}
32     return res;
33 }
34 opt p[mxn];
35 void solve(int l,int r){
36     if(l>=r)return;
37     int mid=(l+r)>>1;
38     int l1=l,l2=mid+1;
39     for(int i=l;i<=r;i++){
40         if(a[i].flag==1 && a[i].ti<=mid)add(a[i].y,a[i].a);
41         else if(a[i].flag==2 && a[i].ti>mid) ans[a[i].id]+=ask(a[i].y)*a[i].a;
42     }
43     for(int i=l;i<=r;i++)if(a[i].flag==1 && a[i].ti<=mid)add(a[i].y,-a[i].a);
44     for(int i=l;i<=r;i++){
45         if(a[i].ti<=mid) p[l1++]=a[i];
46         else p[l2++]=a[i];
47     }
48     for(int i=l;i<=r;i++)a[i]=p[i];
49     solve(l,mid);solve(mid+1,r);
50     return;
51 }
52 int main(){
53     int i,j,S;
54     S=read();n=read();
55     int op,X1,Y1,X2,Y2,w;
56     while(1){
57         op=read();
58         if(op==3)break;
59         if(op==1){
60             X1=read();Y1=read();w=read();
61             a[++cnt].x=X1;a[cnt].y=Y1;a[cnt].a=w;a[cnt].flag=1;a[cnt].ti=cnt;
62         }
63         else{
64             X1=read()-1;Y1=read()-1;X2=read();Y2=read();
65             a[++cnt].x=X1;a[cnt].y=Y1;a[cnt].a=1;a[cnt].flag=2;a[cnt].ti=cnt;a[cnt].id=++ict;
66             a[++cnt].x=X1;a[cnt].y=Y2;a[cnt].a=-1;a[cnt].flag=2;a[cnt].ti=cnt;a[cnt].id=ict;
67             a[++cnt].x=X2;a[cnt].y=Y1;a[cnt].a=-1;a[cnt].flag=2;a[cnt].ti=cnt;a[cnt].id=ict;
68             a[++cnt].x=X2;a[cnt].y=Y2;a[cnt].a=1;a[cnt].flag=2;a[cnt].ti=cnt;a[cnt].id=ict;
69             ans[ict]=(X2-X1)*(Y2-Y1)*S;
70         }
71     }
72     sort(a+1,a+cnt+1,cmp);
73     solve(1,cnt);
74     for(i=1;i<=ict;i++){
75         printf("%lld\n",ans[i]);
76     }
77     return 0;
78 }

 

posted @ 2016-12-29 18:24  SilverNebula  阅读(164)  评论(0编辑  收藏  举报
AmazingCounters.com