DescriptionYou have a n*n board with an integer in each grid, all at 0 at the beginning, and now you need to maintain two operations:
Command |
Parameter limits |
Content |
1 x y A |
1<=x,y<=n,a is a positive integer |
Add the numbers in the lattice x, Y, plus a |
2 x1 y1 x2 y2 |
1<=x1<= x2<=n 1<=y1<= y2<=n |
Output x1 y1 x2 y2 the number within the rectangle and |
3 |
No |
Terminating programs |
InputEnter the first line of the file with a positive integer n. Next, one action per line. Each command, in addition to the first number, will be different or the last output answer Last_ans, initially last_ans=0.
OutputFor each 2 operation, output a corresponding answer.
Sample Input4
1 2 3 3
2 1 1) 3 3
1 1 1 1
2 1 1) 0 7
3
Sample Output3
5
HINTData size and conventions
1<=n<=500000, no more than 200,000 operations, memory limit 20M, ensure that the answer in the range of int and decoded data is still valid. A comparison: compare bare kd trees. Every 5,000 times it was inserted, the violence was rebuilt again. Code:
#include <iostream> #include <cstdio> #include <algorithm> #define N 200010 #define LL long long using Nam
Espace std;
int n,x1,y1,x2,y2,a,opt,rt,f,p (5000);
int Lastans;
inline int read () {int X=0,f=1;char ch=getchar (); while (ch< ' 0 ' | |
Ch> ' 9 ') {if (ch== '-') F=-1;ch=getchar ();}
while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();}
return x*f;
} struct use{int d[2],mn[2],mx[2],v,l,r;
int sum;
inline int &operator[] (int x) {return d[x];}
Inline friend bool operator< (use A,use b) {return a[f]<b[f];} Inline friend bool operator== (use A,use b) {return a.d[0]==b.d[0]&&a.d[1]==b.d[1];}}
P[n]; inline bool in (int x1,int y1,int x2,int y2,int a,int b,int c,int d) {return x1<=a&&x2>=c&&y1<=b
&&y2>=d; } inline bool Out (int x1,int y1,int x2,int y2,int a,int b,int c,int d) {return x2<a| | x1>c| | y1>d| |
y2<b;
} struct kdtree{use t[n],t;
int cnt; inline void update (int k) {inT L=T[K].L,R=T[K].R;
for (int i=0;i<=1;i++) {t[k].mn[i]=t[k].mx[i]=t[k][i];
if (l) t[k].mn[i]=min (T[k].mn[i],t[l].mn[i]);
if (l) T[k].mx[i]=max (T[k].mx[i],t[l].mx[i]);
if (r) t[k].mn[i]=min (T[k].mn[i],t[r].mn[i]);
if (r) T[k].mx[i]=max (T[k].mx[i],t[r].mx[i]);
} t[k].sum=t[l].sum+t[r].sum+t[k].v;
} int query (int k,int x1,int y1,int x2,int y2) {if (!k) return 0;
ll ans (0);
if (in (X1,y1,x2,y2,t[k].mn[0],t[k].mn[1],t[k].mx[0],t[k].mx[1])) return t[k].sum;
if (out (x1,y1,x2,y2,t[k].mn[0],t[k].mn[1],t[k].mx[0],t[k].mx[1])) return 0;
if (in (X1,y1,x2,y2,t[k][0],t[k][1],t[k][0],t[k][1])) ans+=t[k].v;
Ans+=query (t[k].l,x1,y1,x2,y2) +query (t[k].r,x1,y1,x2,y2);
return ans;
} void Insert (int &k,bool d) {if (!k) {k=++cnt;
T[K][0]=T[K].MN[0]=T[K].MX[0]=T[0];
T[K][1]=T[K].MN[1]=T[K].MX[1]=T[1];
} if (T==t[k]) {T[K].V+=T.V,T[K].SUM+=T.V;
Return } if (T[d]<t[k][d]) inSERT (t[k].l,d^1);
else insert (t[k].r,d^1);
Update (k);
} int rebuild (int l,int R,int d) {if (l>r) return 0;f=d;
int mid= (L+R) >>1;
Nth_element (p+l,p+mid,p+r+1);
T[mid]=p[mid];
T[mid].l=rebuild (l,mid-1,d^1);
T[mid].r=rebuild (mid+1,r,d^1);
Update (mid); return mid;
}}KD;
int main () {n=read ();
while (1) {opt=read ();
if (opt==3) break;
if (opt==1) {x1=read (); Y1=read (); A=read ();
X1^=lastans;y1^=lastans;a^=lastans; Kd. T[0]=X1;KD. T[1]=Y1;KD. T.V=KD.
T.sum=a;
Kd.insert (rt,0);
if (kd.cnt==p) {for (int j=1;j<=kd.cnt;j++) P[J]=KD.T[J];
Rt=kd.rebuild (1,kd.cnt,0), p+=5000;
}} else{X1=read (); Y1=read (); X2=read (); Y2=read ();
X1^=lastans;y1^=lastans;x2^=lastans;y2^=lastans;
Lastans=kd.query (RT,X1,Y1,X2,Y2);
printf ("%d\n", Lastans); }
}
}