BZOJ2683: 简单题

题解: cdq分治一下即可 把查询分成四个矩形

#include <bits/stdc++.h>
const int MAXN=8e5+10;
const int NM=5e5+10;
using namespace std;
const int inf=1e9;
typedef struct node{
	int x,y,id,vul;
}node;
node d[MAXN],p[MAXN];int ans[NM];
int sum[NM],n;
int get_id(int x){return x&(-x);}
void add(int x,int vul){
	for(int i=x;i<=n;i+=get_id(i))sum[i]+=vul;
}
int Sum(int x){
	int ans1=0;
	for(int i=x;i>0;i-=get_id(i))ans1+=sum[i];
	return ans1;
}
void clear(int x){
	if(!x)return ;
	for(int i=x;i<=n;i+=get_id(i))sum[i]=0;
}
void merge(int l,int mid,int r){
	int i=l;int j=mid+1;int cnt=0;
	//cout<<l<<"++++"<<r<<endl;
	while(i<=mid&&j<=r){
		while(i<=mid&&d[i].x<=d[j].x){
			if(!d[i].id)add(d[i].y,d[i].vul);
			p[++cnt]=d[i];i++;
		}
		if(d[j].id>0)ans[d[j].id]+=Sum(d[j].y);
		if(d[j].id<0)ans[-1*d[j].id]-=Sum(d[j].y);
		p[++cnt]=d[j];j++;
		//cout<<l<<":::"<<r<<i<<" "<<j<<endl;
	}
	if(j<=r){
		for(;j<=r;j++){
			if(d[j].id>0)ans[d[j].id]+=Sum(d[j].y);
			if(d[j].id<0)ans[-1*d[j].id]-=Sum(d[j].y);
			p[++cnt]=d[j];
		}
	}
	//cout<<"sb"<<endl;
	if(i<=mid){
		for(;i<=mid;i++)p[++cnt]=d[i];
	}
	//cout<<"sb"<<endl;
	for(int i=1;i<=cnt;i++)d[l+i-1]=p[i],clear(p[i].y);
}
void cdq(int l,int r){
	//cout<<l<<" "<<r<<endl;
	if(l>=r)return ;
	int mid=(l+r)>>1;
	cdq(l,mid);
	cdq(mid+1,r);
	merge(l,mid,r);
	//cout<<l<<" "<<r<<" "<<mid<<endl;
	//for(int i=l;i<=r;i++)cout<<d[i].x<<"===="<<d[i].y<<" "<<d[i].id<<endl;
}
int main(){
	scanf("%d",&n);
	int op,x1,x2,y1,y2;int cnt=0,cnt1=0;
	for(int i=1;;i++){
		scanf("%d",&op);
		if(op==3)break;
		cnt1++;
		if(op==1)scanf("%d%d%d",&x1,&y1,&y2),d[++cnt].x=x1,d[cnt].y=y1,d[cnt].id=0,d[cnt].vul=y2,ans[i]=inf;
		else{
			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);ans[i]=0;
			d[++cnt].x=x2;d[cnt].y=y2;d[cnt].id=i;
			d[++cnt].x=x1-1;d[cnt].y=y1-1;d[cnt].id=i;
			d[++cnt].x=x1-1;d[cnt].y=y2;d[cnt].id=-i;
			d[++cnt].x=x2;d[cnt].y=y1-1;d[cnt].id=-i;
		}
	}
	cdq(1,cnt);
	//cout<<cnt1<<endl;
	for(int i=1;i<=cnt1;i++){
		if(ans[i]!=inf)printf("%d\n",ans[i]);
	}
	return 0;
}

 

2683: 简单题

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 2225  Solved: 916
[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。
posted @ 2018-08-12 01:40  wang9897  阅读(139)  评论(0编辑  收藏  举报