bzoj4066 简单题

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。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案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,保证答案在int范围内并且解码之后数据仍合法。
样例解释见OJ2683
新加数据一组,但未重测----2015.05.24

正解:$kd-tree$。

省选前发现这题卡空间,当时还不会做。然而现在学了$kd-tree$,就简单多了。。

不过我还是调了好久,主要是一些边界条件错误和两矩形相交的剪枝写萎了。。

注意每加入一定的点就要重构$kd-tree$,因为丧心病狂的出题人可能会卡你。。

还有就是重构的时候左右儿子一定要先清空,子树和也要赋值成单点值。

判断两矩形相交,只要有一维不相交那么两矩形就是不相交的,我就是因为这里才$T$的。。

  1 //It is made by wfj_2048~
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <cstdio>
  7 #include <vector>
  8 #include <cmath>
  9 #include <queue>
 10 #include <stack>
 11 #include <map>
 12 #include <set>
 13 #define inf (1<<30)
 14 #define N (400010)
 15 #define il inline
 16 #define RG register
 17 #define ll long long
 18 #define fi01() for (RG int i=0;i<=1;++i)
 19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
 20 
 21 using namespace std;
 22 
 23 int K,n,rt,sz,opt,ans;
 24 
 25 struct node{
 26     
 27     int a[2],mn[2],mx[2],l,r,v,sum;
 28     
 29     bool operator < (const node &t) const{
 30     return a[K]<t.a[K] || (a[K]==t.a[K] && a[K^1]<t.a[K^1]);
 31     }
 32     
 33 }t[N],S,S1,S2;
 34 
 35 il int gi(){
 36     RG int x=0,q=1; RG char ch=getchar();
 37     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
 38     if (ch=='-') q=-1,ch=getchar();
 39     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
 40     return q*x;
 41 }
 42 
 43 il void merge(RG int x){
 44     fi01(){
 45     if (t[x].l){
 46         t[x].mn[i]=min(t[x].mn[i],t[t[x].l].mn[i]);
 47         t[x].mx[i]=max(t[x].mx[i],t[t[x].l].mx[i]);
 48     }
 49     if (t[x].r){
 50         t[x].mn[i]=min(t[x].mn[i],t[t[x].r].mn[i]);
 51         t[x].mx[i]=max(t[x].mx[i],t[t[x].r].mx[i]);
 52     }
 53     }
 54     t[x].sum=t[t[x].l].sum+t[t[x].r].sum+t[x].v; return;
 55 }
 56 
 57 il int rebuild(RG int l,RG int r,RG int p){
 58     K=p; RG int mid=(l+r)>>1; nth_element(t+l,t+mid,t+r+1);
 59     fi01() t[mid].mn[i]=t[mid].mx[i]=t[mid].a[i];
 60     t[mid].sum=t[mid].v,t[mid].l=t[mid].r=0;
 61     if (l<mid) t[mid].l=rebuild(l,mid-1,p^1);
 62     if (r>mid) t[mid].r=rebuild(mid+1,r,p^1);
 63     merge(mid); return mid;
 64 }
 65 
 66 il void insert(RG int x,RG int p){
 67     K=p;
 68     if (S<t[x]){ if (!t[x].l) t[t[x].l=++sz]=S; else insert(t[x].l,p^1); }
 69     else{ if (!t[x].r) t[t[x].r=++sz]=S; else insert(t[x].r,p^1); }
 70     merge(x); return;
 71 }
 72 
 73 il int sa(node a,node b){
 74     fi01() if (b.mn[i]>a.a[i] || a.a[i]>b.mx[i]) return 0; return 1;
 75 }
 76 
 77 il int sb(node a,node b){
 78     fi01() if (b.mn[i]>a.mn[i] || a.mx[i]>b.mx[i]) return 0; return 1;
 79 }
 80 
 81 il int sc(node a,node b){
 82     fi01() if (a.mx[i]<b.mn[i] || a.mn[i]>b.mx[i]) return 0; return 1;
 83 }
 84 
 85 il void query(RG int x){
 86     if (!x) return; if (sa(t[x],S)) ans+=t[x].v;
 87     if (t[x].l){
 88     if (sb(t[t[x].l],S)) ans+=t[t[x].l].sum;
 89     else if (sc(t[t[x].l],S)) query(t[x].l);
 90     }
 91     if (t[x].r){
 92     if (sb(t[t[x].r],S)) ans+=t[t[x].r].sum;
 93     else if (sc(t[t[x].r],S)) query(t[x].r);
 94     }
 95     return;
 96 }
 97 
 98 il void work(){
 99     n=gi();
100     while (1){
101     opt=gi(); if (opt==3) break;
102     if (opt==1){
103         S.a[0]=gi()^ans,S.a[1]=gi()^ans,S.v=gi()^ans;
104         fi01() S.mn[i]=S.mx[i]=S.a[i]; S.sum=S.v,S.l=S.r=0;
105         if (!sz) t[rt=++sz]=S; else insert(rt,0);
106         if (sz%5000==0) rt=rebuild(1,sz,0);
107     }
108     if (opt==2){
109         S1.a[0]=gi()^ans,S1.a[1]=gi()^ans;
110         S2.a[0]=gi()^ans,S2.a[1]=gi()^ans;
111         if (S1.a[0]>S2.a[0]) swap(S1.a[0],S2.a[0]);
112         if (S1.a[1]>S2.a[1]) swap(S1.a[1],S2.a[1]);
113         fi01() S.mn[i]=S1.a[i],S.mx[i]=S2.a[i];
114         ans=0,query(rt),printf("%d
",ans);
115     }
116     }
117     return;
118 }
119 
120 int main(){
121     File("simple");
122     work();
123     return 0;
124 }
原文地址:https://www.cnblogs.com/wfj2048/p/6949810.html