[bzoj4066]简单题

来源:互联网 发布:护腰带腰椎间盘 知乎 编辑:程序博客网 时间:2024/05/19 08:03

4066: 简单题

Time Limit: 50 Sec Memory Limit: 20 MB
Submit: 1563 Solved: 420
[Submit][Status][Discuss]
Description

这里写图片描述

Input

输入文件第一行一个正整数N。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案last_ans,初始时last_ans=0。
Output

对于每个2操作,输出一个对应的答案。
Sample Input

41 2 3 32 1 1 3 31 1 1 12 1 1 0 73

Sample Output

35

HINT

数据规模和约定

1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。

KD树模板题。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=200010;int n,ans,siz,root,o,D;struct S{    int v,sum,d[2],minn[2],maxn[2],l,r;    int &operator [](int x){        return d[x];    }    bool operator == (const S &x)const{        return x.d[0]==d[0]&&x.d[1]==d[1];    }    bool operator < (const S &x)const{        return d[D]<x.d[D];    }}tr[N],p[N],now;inline int IN(){    int x=0;char ch=getchar();    while(ch<'0'||ch>'9') ch=getchar();    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x;}inline void update(int k){    int l=tr[k].l,r=tr[k].r,i;    tr[k].sum=tr[k].v+tr[l].sum+tr[r].sum;    for(i=0;i<=1;++i){        tr[k].minn[i]=tr[k].maxn[i]=tr[k][i];        if(l){            tr[k].minn[i]=min(tr[k].minn[i],tr[l].minn[i]);            tr[k].maxn[i]=max(tr[k].maxn[i],tr[l].maxn[i]);         }        if(r){            tr[k].minn[i]=min(tr[k].minn[i],tr[r].minn[i]);            tr[k].maxn[i]=max(tr[k].maxn[i],tr[r].maxn[i]);         }    }}inline void insert(int &k,int flag){    if(!k){        k=++siz;        tr[k][0]=tr[k].minn[0]=tr[k].maxn[0]=now[0];        tr[k][1]=tr[k].minn[1]=tr[k].maxn[1]=now[1];    }    if(now==tr[k]){        tr[k].sum+=now.sum;        tr[k].v+=now.v;        return ;        }    if(now[flag]<tr[k][flag]) insert(tr[k].l,flag^1);    else insert(tr[k].r,flag^1);    update(k); }#define mid (l+r)/2inline int rebuild(int l,int r,int flag){    if(l>r) return 0;    D=flag;nth_element(p+l,p+mid,p+r+1);    tr[mid]=p[mid];    tr[mid].l=rebuild(l,mid-1,flag^1);    tr[mid].r=rebuild(mid+1,r,flag^1);    update(mid);    return mid;}inline bool in(int x1,int y1,int x2,int y2,int X1,int Y1,int X2,int Y2){    return x1<=X1&&x2>=X2&&y1<=Y1&&y2>=Y2;}inline bool out(int x1,int y1,int x2,int y2,int X1,int Y1,int X2,int Y2){    return x1>X2||x2<X1||y1>Y2||y2<Y1;}inline int query(int k,int x,int y,int xx,int yy){    if(!k) return 0;    int sum=0;    if(in(x,y,xx,yy,tr[k].minn[0],tr[k].minn[1],tr[k].maxn[0],tr[k].maxn[1])) return tr[k].sum;    if(out(x,y,xx,yy,tr[k].minn[0],tr[k].minn[1],tr[k].maxn[0],tr[k].maxn[1])) return 0;    if(in(x,y,xx,yy,tr[k][0],tr[k][1],tr[k][0],tr[k][1])) sum+=tr[k].v;    return sum+query(tr[k].l,x,y,xx,yy)+query(tr[k].r,x,y,xx,yy);}int main(){    int i,t,x,y,xx,yy,z;    n=IN();    o=10000;    while(1){        t=IN();        if(t==3) break;        x=IN();y=IN();        x^=ans;y^=ans;        if(t==1){            z=IN();z^=ans;            now[0]=x;now[1]=y;            now.v=now.sum=z;            insert(root,0);            if(siz==o){                for(i=1;i<=siz;++i) p[i]=tr[i];                root=rebuild(1,siz,0);                o+=10000;            }        }        if(t==2){            xx=IN();yy=IN();            xx^=ans;yy^=ans;            ans=query(root,x,y,xx,yy);            printf("%d\n",ans);        }    }}
1 0
原创粉丝点击