BZOJ 2683 简单题
2683: 简单题
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 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
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
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;
}

浙公网安备 33010602011771号