BZOJ 2683 简单题

Posted zhangenming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 2683 简单题相关的知识,希望对你有一定的参考价值。

2683: 简单题

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 1798  Solved: 729
[Submit][Status][Discuss]

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

Sample Output

3
5

HINT

 

1<=N<=500000,操作数不超过200000个,内存限制20M。

对于100%的数据,操作1中的A不超过2000。

 

Source

裸的CDQ分治

技术分享图片
  1 #include <bits/stdc++.h>
  2 #define inf 10000000
  3 #define ll long long
  4 using namespace std;
  5 inline int read(){
  6     int x=0;int f=1;char ch=getchar();
  7     while(!isdigit(ch)) {if(ch==-) f=-1;ch=getchar();}
  8     while(isdigit(ch)) {x=x*10+ch-0;ch=getchar();}
  9     return x*f;
 10 }
 11 const int MAXN=1e6+10;
 12 struct node{
 13     int x1,y1,x2,y2;
 14     int x,y,v;
 15     int op,id;
 16 }a[MAXN],b[MAXN],d[MAXN];
 17 int ans[MAXN],c[MAXN],n,m;
 18 inline int lowbit(int x) {return x&-x;}
 19 inline void add(int x,int vv){
 20     while(x<=MAXN){
 21         c[x]+=vv;
 22         x+=lowbit(x);
 23     }
 24 }
 25 inline int get(int x){
 26     int ans=0;
 27     while(x){
 28         ans+=c[x];
 29         x-=lowbit(x);
 30     }
 31     return ans;
 32 }
 33 inline bool cmp1(node n,node m){
 34     return n.x1<m.x1;
 35 }
 36 inline bool cmp2(node n,node m){
 37     return n.x2<m.x2;
 38 }
 39 inline bool cmp3(node n,node m){
 40     return n.x<m.x;
 41 }
 42 void CDQ(int l,int r){
 43     if(l!=r){
 44         int mid=(r+l)>>1;
 45         CDQ(l,mid);CDQ(mid+1,r);
 46         int p=0;
 47         for(int i=l;i<=mid;i++){
 48             if(a[i].op==1){
 49                 b[++p]=a[i];
 50             }
 51         }
 52         sort(b+1,b+p+1,cmp3);
 53         int p1=0;
 54         for(int i=mid+1;i<=r;i++){
 55             if(a[i].op==2){
 56                 d[++p1]=a[i];
 57             }
 58         }
 59         sort(d+1,d+p1+1,cmp1);
 60         int i1=1,i2=1;
 61         while(i1<=p&&i2<=p1){
 62             if(b[i1].x<=d[i2].x1-1){
 63                 add(b[i1].y,b[i1].v);
 64                 i1++;
 65             }
 66             else{
 67                 ans[d[i2].id]-=get(d[i2].y2)-get(d[i2].y1-1);
 68                 i2++;
 69             }
 70         }
 71         for(int i=i2;i<=p1;i++){
 72             ans[d[i].id]-=get(d[i].y2)-get(d[i].y1-1);
 73         }
 74         for(int i=1;i<=i1-1;i++){
 75             add(b[i].y,-b[i].v);
 76         }
 77         sort(d+1,d+p1+1,cmp2);
 78         i1=1,i2=1;
 79         while(i1<=p&&i2<=p1){
 80             if(b[i1].x<=d[i2].x2){
 81                 add(b[i1].y,b[i1].v);
 82                 i1++;
 83             }
 84             else{
 85                 ans[d[i2].id]+=get(d[i2].y2)-get(d[i2].y1-1);
 86                 i2++;
 87             }
 88         }
 89         for(int i=i2;i<=p1;i++){
 90             ans[d[i].id]+=get(d[i].y2)-get(d[i].y1-1);
 91         }
 92         for(int i=1;i<=i1-1;i++){
 93             add(b[i].y,-b[i].v);
 94         }
 95     }
 96 }
 97 int main(){
 98     n=read();
 99     a[++m].op=read();
100     while(a[m].op!=3){
101         a[m].id=m;
102         if(a[m].op==1) a[m].x=read(),a[m].y=read(),a[m].v=read();
103         else a[m].x1=read(),a[m].y1=read(),a[m].x2=read(),a[m].y2=read();
104         a[++m].op=read();
105     }
106     CDQ(1,m-1);
107     for(int i=1;i<=m;i++){
108         if(a[i].op==2) printf("%d\n",ans[i]);
109     }
110     return 0;
111 }
View Code

 














以上是关于BZOJ 2683 简单题的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2683 简单题

bzoj 2683: 简单题

BZOJ 2683 简单题

[BZOJ2683][BZOJ4066]简单题

bzoj2683简单题 cdq分治

BZOJ2683: 简单题(CDQ分治 + 树状数组)