Bzoj4066 简单题

Time Limit: 50 Sec  Memory Limit: 20 MB
Submit: 2185  Solved: 581

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

Source

 

同Bzoj2683。

嘛,真是简单题啊,才调了两天就过了。

由于强制在线,所以不能像2683那样各种方法乱搞,只能老实写K-Dtree(好像还有块链之类的解法)

K-Dtree定期重构,强行维护数据。常数写不好的话会T飞。

之前把47行的左右边界取错了,时间复杂度直接突破天际。

 

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 #define LL long long
  9 using namespace std;
 10 const int mxn=250010;
 11 LL read(){
 12     LL x=0,f=1;char ch=getchar();
 13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 15     return x*f;
 16 }
 17 struct node{
 18     int l,r;
 19     int min[2],max[2];
 20     int d[2];
 21     int w;
 22     LL sum;
 23 }t[mxn];
 24 int root=0,nowD;
 25 int cmp(const node a,const node b){
 26     return a.d[nowD]<b.d[nowD];
 27 }
 28 int n,cnt;
 29 int lim=0;
 30 inline void pushup(int rt,int x){
 31     t[rt].max[0]=max(t[rt].max[0],t[x].max[0]);
 32     t[rt].max[1]=max(t[rt].max[1],t[x].max[1]);
 33     t[rt].min[0]=min(t[rt].min[0],t[x].min[0]);
 34     t[rt].min[1]=min(t[rt].min[1],t[x].min[1]);
 35     return;
 36 }
 37 inline bool in(int x1,int y1,int x2,int y2,int k){
 38     return (x1<=t[k].min[0] && t[k].max[0]<=x2 &&
 39         y1<=t[k].min[1] && t[k].max[1]<=y2);
 40 }
 41 inline bool out(int x1,int y1,int x2,int y2,int k){
 42     return (x1>t[k].max[0] || x2<t[k].min[0] || y1>t[k].max[1] || y2<t[k].min[1]);
 43 }
 44 int Build(int l,int r,int D){
 45     if(l>r)return 0;
 46     nowD=D;int mid=(l+r)>>1;
 47     nth_element(t+l,t+mid,t+r+1,cmp);///
 48     t[mid].max[0]=t[mid].min[0]=t[mid].d[0];
 49     t[mid].max[1]=t[mid].min[1]=t[mid].d[1];
 50     t[mid].sum=t[mid].w;
 51     //
 52     t[mid].l=Build(l,mid-1,D^1);
 53     if(t[mid].l)pushup(mid,t[mid].l);
 54     t[mid].r=Build(mid+1,r,D^1);
 55     if(t[mid].r)pushup(mid,t[mid].r);
 56     //
 57     t[mid].sum=t[mid].w+t[t[mid].l].sum+t[t[mid].r].sum;
 58     return mid;
 59 }
 60 void insert(int &now,int x,int D){
 61     if(!now){now=x;return;}
 62     if(t[x].d[D]==t[now].d[D] && t[x].d[!D]==t[now].d[!D]){
 63         t[now].w+=t[x].w;
 64         t[now].sum+=t[x].w;
 65         --cnt;
 66         return;
 67     }
 68     if(t[x].d[D]<t[now].d[D]){
 69         insert(t[now].l,x,D^1);
 70         pushup(now,t[now].l);
 71     }
 72     else{
 73         insert(t[now].r,x,D^1);
 74         pushup(now,t[now].r);
 75     }
 76     t[now].sum=t[now].w+t[t[now].l].sum+t[t[now].r].sum;
 77     return;
 78 }
 79 LL query(int rt,int x1,int y1,int x2,int y2){
 80     if(!rt)return 0;
 81     LL res=0;
 82     if(in(x1,y1,x2,y2,rt)){return t[rt].sum;}
 83     if(out(x1,y1,x2,y2,rt)){return 0;}
 84     if(x1<=t[rt].d[0] && t[rt].d[0]<=x2 && 
 85         y1<=t[rt].d[1] && t[rt].d[1]<=y2) res+=t[rt].w;
 86     res+=query(t[rt].l,x1,y1,x2,y2)+query(t[rt].r,x1,y1,x2,y2);
 87     return res;
 88 }
 89 int main(){
 90     int i,j,op,x,y,w;
 91     n=read();lim=9000;
 92     LL lans=0;int X1,X2,Y1,Y2;
 93     while(1){
 94         op=read();
 95         if(op==3)break;
 96         if(op==1){
 97             t[++cnt].d[0]=read()^lans;t[cnt].d[1]=read()^lans;
 98             t[cnt].w=read()^lans;t[cnt].sum=t[cnt].w;
 99             t[cnt].max[0]=t[cnt].min[0]=t[cnt].d[0];
100             t[cnt].max[1]=t[cnt].min[1]=t[cnt].d[1];
101             insert(root,cnt,0);
102             if(cnt==lim){
103                 lim+=9000;
104                 root=Build(1,cnt,0);
105             }
106         }
107         else{
108  
109             X1=read()^lans;Y1=read()^lans;X2=read()^lans;Y2=read()^lans;
110             lans=query(root,X1,Y1,X2,Y2);
111             printf("%lld\n",lans);
112         }
113     }
114     return 0;
115 }

 

posted @ 2016-12-23 23:25  SilverNebula  阅读(331)  评论(0编辑  收藏  举报
AmazingCounters.com