题目描述:
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 | 无 | 终止程序 |
强制在线,异或lastans.
1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。
题目分析:
带插入二维数点,然而用平衡因子重构(30000ms)还不如插入5000个点整棵树重构(22000ms)快。。。
Code:
#include<bits/stdc++.h>
#define maxn 200005
using namespace std;
char cb[1<<18],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<18,stdin),cs==ct)?0:*cs++)
inline void read(int &a){
char c;bool f=0;while(!isdigit(c=getc())) c=='-'&&(f=1);
for(a=c-'0';isdigit(c=getc());a=a*10+c-'0'); f&&(a=-a);
}
int n,m,rt,tot,id[maxn],*mtp,x[2],y[2],ans;
struct node{
int d[2],mn[2],mx[2],ch[2],nd,s,x,v;
void upd(node *t){
mn[0]=mx[0]=d[0],mn[1]=mx[1]=d[1],s=1,x=v;
for(int i=0;i<2;i++) if(ch[i]){
s+=t[ch[i]].s,x+=t[ch[i]].x;
for(int j=0;j<2;j++) mn[j]=min(mn[j],t[ch[i]].mn[j]),mx[j]=max(mx[j],t[ch[i]].mx[j]);
}
}
}t[maxn];
template<int D>bool cmp(int i,int j){return t[i].d[D]<t[j].d[D];}
bool (*fun[2])(int i,int j)={cmp<0>,cmp<1>};
void build(int &i,int l,int r,int D){
if(l>r) return void(i=0);
int o=(l+r)>>1;nth_element(id+l,id+o,id+r+1,fun[D]),i=id[o];
build(t[i].ch[0],l,o-1,D^1),build(t[i].ch[1],o+1,r,D^1);
t[i].nd=D,t[i].upd(t);
}
void ins(int &i,int x,int D){
if(!i) {t[i=x].upd(t),t[i].nd=D;return;}
ins(t[i].ch[fun[D](i,x)],x,D^1),t[i].upd(t);
if(t[i].s*0.75<max(t[t[i].ch[0]].s,t[t[i].ch[1]].s)) mtp=&i;
}
void pia(int i){
if(!i) return;
id[++id[0]]=i,pia(t[i].ch[0]),pia(t[i].ch[1]);
}
void qry(int i){
if(!i||x[1]<t[i].mn[0]||x[0]>t[i].mx[0]||y[1]<t[i].mn[1]||y[0]>t[i].mx[1]) return;
if(x[0]<=t[i].mn[0]&&t[i].mx[0]<=x[1]&&y[0]<=t[i].mn[1]&&t[i].mx[1]<=y[1]) {ans+=t[i].x;return;}
if(x[0]<=t[i].d[0]&&t[i].d[0]<=x[1]&&y[0]<=t[i].d[1]&&t[i].d[1]<=y[1]) ans+=t[i].v;
qry(t[i].ch[0]),qry(t[i].ch[1]);
}
int main()
{
read(n);
int op;
while(read(op),op<3){
if(op==1){
read(x[0]),read(y[0]),t[++tot].d[0]=x[0]^ans,t[tot].d[1]=y[0]^ans;
read(t[tot].v),t[tot].v^=ans;
mtp=0,ins(rt,tot,0);
if(mtp) id[0]=0,pia(*mtp),build(*mtp,1,id[0],t[*mtp].nd);
}
else
read(x[0]),read(y[0]),read(x[1]),read(y[1]),x[0]^=ans,y[0]^=ans,x[1]^=ans,y[1]^=ans,
ans=0,qry(rt),printf("%d\n",ans);
}
}