你有一个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。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案last_ans,初始时last_ans=0。
kd-tree练习题
#include<cstdio>
#include<string>
#include<algorithm>
#define ls t[o].s[0]
#define rs t[o].s[1]
using namespace std;
const int maxn=3e5+5;
int N,WD,rt,ans,top,cur,rub[maxn];
struct P{int d[2],w;}p[maxn];
struct T{int mn[2],mx[2],s[2],sz,sm;P tp;}t[maxn];
inline bool operator <(P a,P b) {return a.d[WD]<b.d[WD];}
inline int read() {
int ret=0,f=1;char ch=getchar();
for (; !isdigit(ch); ch=getchar()) if (ch=='-') f=-f;
for (; isdigit(ch); ch=getchar()) ret=ret*10+ch-48;
return ret*f;
}
inline int newnode() {return top?rub[top--]:++cur;}
inline void pushup(int o) {
for (int i=0; i<2; i++) {
t[o].mn[i]=t[o].mx[i]=t[o].tp.d[i];
if (ls) t[o].mn[i]=min(t[o].mn[i],t[ls].mn[i]),t[o].mx[i]=max(t[o].mx[i],t[ls].mx[i]);
if (rs) t[o].mn[i]=min(t[o].mn[i],t[rs].mn[i]),t[o].mx[i]=max(t[o].mx[i],t[rs].mx[i]);
}
t[o].sz=1+t[ls].sz+t[rs].sz,t[o].sm=t[o].tp.w+t[ls].sm+t[rs].sm;
}
int build(int L,int R,int wd) {
if (L>R) return 0;
int mid=L+(R-L>>1),o=newnode();
WD=wd,nth_element(p+L,p+mid,p+R+1),t[o].tp=p[mid];
ls=build(L,mid-1,wd^1),rs=build(mid+1,R,wd^1);
pushup(o);return o;
}
void pia(int o,int num) {
if (ls) pia(ls,num);
p[num+t[ls].sz+1]=t[o].tp,rub[++top]=o;
if (rs) pia(rs,num+t[ls].sz+1);
}
inline void check(int &o,int wd) {
if (0.75*t[o].sz<t[ls].sz||0.75*t[o].sz<t[rs].sz) pia(o,0),o=build(1,t[o].sz,wd);
}
void Insert(P tmp,int &o,int wd) {
if (!o) {o=newnode(),t[o].tp=tmp,ls=rs=0,pushup(o);return;}
if (t[o].tp.d[wd]>=tmp.d[wd]) Insert(tmp,ls,wd^1);
else Insert(tmp,rs,wd^1);
pushup(o),check(o,wd);
}
inline bool in(int x,int y,int l,int r,int X,int Y,int L,int R) {return x>=X&&l<=L&&y>=Y&&r<=R;}
inline bool out(int x,int y,int l,int r,int X,int Y,int L,int R) {return x>L||l<X||y>R||r<Y;}
int Query(int x,int y,int l,int r,int o) {
if (!o) return 0;
if (in(t[o].mn[0],t[o].mn[1],t[o].mx[0],t[o].mx[1],x,y,l,r)) return t[o].sm;
if (out(t[o].mn[0],t[o].mn[1],t[o].mx[0],t[o].mx[1],x,y,l,r)) return 0;
int ret=0;
if (in(t[o].tp.d[0],t[o].tp.d[1],t[o].tp.d[0],t[o].tp.d[1],x,y,l,r)) ret+=t[o].tp.w;
return Query(x,y,l,r,ls)+Query(x,y,l,r,rs)+ret;
}
int main() {
N=read();
P tmp;
for (int opt=read(),x,y,l,r; opt^3; opt=read())
if (opt==1) {
tmp.d[0]=read()^ans,tmp.d[1]=read()^ans,tmp.w=read()^ans;
Insert(tmp,rt,0);
} else {
x=read()^ans,y=read()^ans,l=read()^ans,r=read()^ans;
printf("%d\n",ans=Query(x,y,l,r,rt));
}
return 0;
}