题目大意:
给你一个N*N的棋盘,每个格子初始值v=0,支持两种操作:
1、v(x,y)+=k
2、query(x1,y1,x2,y2)
Input
输入文件第一行一个正整数N。
接下来每行一个操作。每条命令除第一个数字之外,均要异或上一次输出的答案last_ans。初始last_ans=0
Output
对于每个2操作,输出一个对应的答案。
Sample Input
4
1 2 3 3
2 1 1 3 3
1 1 1 1
2 1 1 0 7
3
Sample Output
3
5
Hint
1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。
昨天做了离线版本的,可以用cdq水过去,今天强制在线,是kd-tree的模板题,区间查询和。
#include<bits/stdc++.h>
using namespace std;
const int Maxn=500005;
typedef long long ll;
inline ll getll(){
ll res=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))res=res*10+c-'0',c=getchar();
return res;
}
ll n,cnt,root,nowst;
ll ans;
struct Node{
ll p[2],son[2];
ll l[2],r[2];
ll v,sum;
inline void newnode(ll *_p,ll val){
for(ll i=0;i<2;++i){
p[i]=l[i]=r[i]=_p[i];
son[i]=0;
}
v=sum=val;
}
}a[Maxn],nd;
#define ls a[x].son[0]
#define rs a[x].son[1]
bool check(const Node&A,const Node&B){
for(ll i=0;i<2;++i)
if(A.p[i]!=B.p[i])return 0;
return 1;
}
void maintain(ll x){
a[x].sum=a[x].v;
if(ls){
for(ll i=0;i<2;++i)
a[x].l[i]=min(a[x].l[i],a[ls].l[i]),
a[x].r[i]=max(a[x].r[i],a[ls].r[i]);
a[x].sum+=a[ls].sum;
}
if(rs){
for(ll i=0;i<2;++i)
a[x].l[i]=min(a[x].l[i],a[rs].l[i]),
a[x].r[i]=max(a[x].r[i],a[rs].r[i]);
a[x].sum+=a[rs].sum;
}
}
void insert(ll &x,ll state){
if(!x)return a[x=++cnt].newnode(nd.p,nd.v),void();
if(check(a[x],nd))return a[x].v+=nd.v,a[x].sum+=nd.v,void();
if(nd.p[state]<a[x].p[state])insert(ls,state^1);
else insert(rs,state^1);
maintain(x);
}
ll query(ll x,ll x1,ll y1,ll x2,ll y2){
if(!x||a[x].l[0]>x2||a[x].r[0]<x1||a[x].l[1]>y2||a[x].r[1]<y1)return 0;
if(x1<=a[x].l[0]&&a[x].r[0]<=x2&&y1<=a[x].l[1]&&a[x].r[1]<=y2)return a[x].sum;
ll ret=0;
if(x1<=a[x].p[0]&&a[x].p[0]<=x2&&y1<=a[x].p[1]&&a[x].p[1]<=y2)ret+=a[x].v;
return ret+query(ls,x1,y1,x2,y2)+query(rs,x1,y1,x2,y2);
}
int main(){
n=getll();
while(233){
ll op=getll();
if(op==3)break;
if(op==1){
for(ll i=0;i<2;++i)
nd.p[i]=getll()^ans;
nd.v=getll()^ans;
insert(root,0);
}else {
ll x1=getll()^ans,y1=getll()^ans,x2=getll()^ans,y2=getll()^ans;
ans=query(root,x1,y1,x2,y2);
cout<<ans<<'\n';
}
}
return 0;
}