简单题
Time Limit: 50 Sec Memory Limit: 128 MB
Submit: 1324 Solved: 527
[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>
using namespace std;
const int maxn = 200005;
struct da
{
int x,y,val,type,id,time;
};
da in[4*maxn],buf[4*maxn];
int ans[maxn],n,cnt,cntt,cntid;
bool cmp(da a,da b)
{
if(a.x==b.x&&a.y==b.y)return a.type<b.type;
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
void ins(int x1,int y1,int x2,int y2)
{
cntt++;cntid++;
in[++cnt]=(da){x2,y2,1,2,cntid,cntt};
in[++cnt]=(da){x1-1,y2,-1,2,cntid,cntt};
in[++cnt]=(da){x2,y1-1,-1,2,cntid,cntt};
in[++cnt]=(da){x1-1,y1-1,1,2,cntid,cntt};
}
int fenwick[maxn];
void add(int loc,int delta)
{
for(;loc<=n;loc+=loc&-loc)
fenwick[loc]+=delta;
}
int sum(int loc)
{
int ret=0;
for(;loc>0;loc-=loc&-loc)
ret+=fenwick[loc];
return ret;
}
void cdq(int l,int r)
{
if(l==r)return;
int mid=l+r>>1;
for(int i=l;i<=r;i++)
{
if(in[i].time<=mid && in[i].type==1)add(in[i].y,in[i].val);
if(in[i].time>mid && in[i].type==2)ans[in[i].id]+=sum(in[i].y)*in[i].val;
cout<<ans[in[i].id]<<" "<<in[i].id<<"\n";
}
for(int i=l;i<=r;i++)
if(in[i].time<=mid && in[i].type==1)
add(in[i].y,-in[i].val);
int l1=l,l2=mid+1;
for(int i=l;i<=r;i++)
if(in[i].time<=mid)
buf[l1++]=in[i];
else
buf[l2++]=in[i];
for(int i=l;i<=r;i++)in[i]=buf[i];
cdq(l,mid);
cdq(mid+1,r);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int fl,a,b,c,d;
scanf("%d",&fl);
if(fl==1)
{
scanf("%d%d%d",&a,&b,&c);
cnt++;cntt++;
in[cnt]=(da){a,b,c,1,0,cntt};
}
else if(fl==2)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
ins(a,b,c,d);
}
}
sort(in+1,in+1+cnt,cmp);
cdq(1,cnt);
for(int i=1;i<=cntid;i++)
printf("%d\n",ans[i]);
return 0;
}
20170506回来改了…
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXN = 300000;
const int MAXM = 4000000;
inline int read(){
int rt=0,fl=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')fl=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){rt=rt*10+ch-'0';ch=getchar();}
return rt*fl;
}
struct obj{
int tag,x,y,delta,ans,time,timeQ;
obj(int a,int b,int c,int d,int e,int f){
tag=a;x=b;y=c;delta=d;time=e;ans=0;timeQ=f;
}
obj(){}
void debug(){
printf("tag=%d x=%d y=%d delta=%d ans=%d time=%d timeQ=%d \n",tag,x,y,delta,ans,time,timeQ);
}
};
obj data[MAXN],buf[MAXN];
int n,s,tr[MAXM],cnt,cntForQ,ans[MAXN];
void add(int loc,int delta){
while(loc<=n){
tr[loc]+=delta;
loc+=loc&(-loc);
}
}
int sum(int loc){
int rt=0;
while(loc>0){
rt+=tr[loc];
loc-=loc&(-loc);
}
return rt;
}
void init(){
scanf("%d%d",&s,&n);
while(1){
int a,b,c,d,e;
a=read();
switch(a){
case 1:
b=read();c=read();d=read();
data[++cnt]=obj(1,b,c,d,cnt,0);
break;
case 2:
b=read();c=read();d=read();e=read();
++cntForQ;
data[++cnt]=obj(2,d,e,1,cnt,cntForQ);
data[++cnt]=obj(2,b-1,c-1,1,cnt,cntForQ);
data[++cnt]=obj(2,b-1,e,-1,cnt,cntForQ);
data[++cnt]=obj(2,d,c-1,-1,cnt,cntForQ);
break;
case 3:
return;
}
}
}
void solve(int l,int r){
if(l==r)return;
int mid = l+r>>1,L=l,R=mid+1,t=data[mid].time;
solve(l,mid);solve(mid+1,r);
for(int i=l;i<=r;i++){
if(L<=mid&&R<=r){
if(data[L].x<data[R].x)
buf[i]=data[L++];
else if(data[L].x==data[R].x){
if(data[L].time<data[R].time){
buf[i]=data[L++];
}
else
buf[i]=data[R++];
}
else
buf[i]=data[R++];
}else if(L<=mid)
buf[i]=data[L++];
else
buf[i]=data[R++];
}
for(int i=l;i<=r;i++)data[i]=buf[i];
for(int i=l;i<=r;i++){
if(data[i].tag == 1 && data[i].time <= t){
add(data[i].y,data[i].delta);
}else if(data[i].tag==2&&data[i].time > t){
data[i].ans += sum(data[i].y);
}
}
for(int i=l;i<=r;i++){
if(data[i].tag == 1 && data[i].time <= t){
add(data[i].y,-data[i].delta);
}
}
}
int main(){
init();
solve(1,cnt);
for(int i=1;i<=cnt;i++){
if(data[i].tag==2){
ans[data[i].timeQ] += data[i].ans * data[i].delta;
}
}
for(int i=1;i<=cntForQ;i++)
printf("%d\n",ans[i]);
return 0;
}