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分治

#include <bits/stdc++.h>
#define inf 10000000
#define ll long long
using namespace std;
inline int read(){
    int x=0;int f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int MAXN=1e6+10;
struct node{
    int x1,y1,x2,y2;
    int x,y,v;
    int op,id;
}a[MAXN],b[MAXN],d[MAXN];
int ans[MAXN],c[MAXN],n,m;
inline int lowbit(int x) {return x&-x;}
inline void add(int x,int vv){
    while(x<=MAXN){
        c[x]+=vv;
        x+=lowbit(x);
    }
}
inline int get(int x){
    int ans=0;
    while(x){
        ans+=c[x];
        x-=lowbit(x);
    }
    return ans;
}
inline bool cmp1(node n,node m){
    return n.x1<m.x1;
}
inline bool cmp2(node n,node m){
    return n.x2<m.x2;
}
inline bool cmp3(node n,node m){
    return n.x<m.x;
}
void CDQ(int l,int r){
    if(l!=r){
        int mid=(r+l)>>1;
        CDQ(l,mid);CDQ(mid+1,r);
        int p=0;
        for(int i=l;i<=mid;i++){
            if(a[i].op==1){
                b[++p]=a[i];
            }
        }
        sort(b+1,b+p+1,cmp3);
        int p1=0;
        for(int i=mid+1;i<=r;i++){
            if(a[i].op==2){
                d[++p1]=a[i];
            }
        }
        sort(d+1,d+p1+1,cmp1);
        int i1=1,i2=1;
        while(i1<=p&&i2<=p1){
            if(b[i1].x<=d[i2].x1-1){
                add(b[i1].y,b[i1].v);
                i1++;
            }
            else{
                ans[d[i2].id]-=get(d[i2].y2)-get(d[i2].y1-1);
                i2++;
            }
        }
        for(int i=i2;i<=p1;i++){
            ans[d[i].id]-=get(d[i].y2)-get(d[i].y1-1);
        }
        for(int i=1;i<=i1-1;i++){
            add(b[i].y,-b[i].v);
        }
        sort(d+1,d+p1+1,cmp2);
        i1=1,i2=1;
        while(i1<=p&&i2<=p1){
            if(b[i1].x<=d[i2].x2){
                add(b[i1].y,b[i1].v);
                i1++;
            }
            else{
                ans[d[i2].id]+=get(d[i2].y2)-get(d[i2].y1-1);
                i2++;
            }
        }
        for(int i=i2;i<=p1;i++){
            ans[d[i].id]+=get(d[i].y2)-get(d[i].y1-1);
        }
        for(int i=1;i<=i1-1;i++){
            add(b[i].y,-b[i].v);
        }
    }
}
int main(){
    n=read();
    a[++m].op=read();
    while(a[m].op!=3){
        a[m].id=m;
        if(a[m].op==1) a[m].x=read(),a[m].y=read(),a[m].v=read();
        else a[m].x1=read(),a[m].y1=read(),a[m].x2=read(),a[m].y2=read();
        a[++m].op=read();
    }
    CDQ(1,m-1);
    for(int i=1;i<=m;i++){
        if(a[i].op==2) printf("%d\n",ans[i]);
    }
    return 0;
}

  

 

posted @ 2017-12-28 21:59  zhangenming  阅读(171)  评论(0编辑  收藏  举报