bzoj4066

分别按照x,y排序

#include<cstdio>
#include<algorithm>
#include<cctype>
using namespace std;
struct data{int d[2],l,r,mn[2],mx[2],sum,val;}tr[200005];
int cmpd,ans=0,x1,x2,y1,y2,rt;

void read(int &x){
    char ch=getchar();x=0;int f=1;
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    x*=f;
}

int cmp(const data &a,const data &b){
    return(a.d[cmpd]<b.d[cmpd]||(a.d[cmpd]==b.d[cmpd]&&a.d[!cmpd]<b.d[!cmpd]));
}

void updata(int now){
    int ls=tr[now].l,rs=tr[now].r;
    if(ls){
        tr[now].mn[0]=min(tr[now].mn[0],tr[ls].mn[0]);
        tr[now].mn[1]=min(tr[now].mn[1],tr[ls].mn[1]);
        tr[now].mx[0]=max(tr[now].mx[0],tr[ls].mx[0]);
        tr[now].mx[1]=max(tr[now].mx[1],tr[ls].mx[1]);
    }
    if(rs){
        tr[now].mn[0]=min(tr[now].mn[0],tr[rs].mn[0]);
        tr[now].mn[1]=min(tr[now].mn[1],tr[rs].mn[1]);
        tr[now].mx[0]=max(tr[now].mx[0],tr[rs].mx[0]);
        tr[now].mx[1]=max(tr[now].mx[1],tr[rs].mx[1]);
    }
    tr[now].sum=tr[ls].sum+tr[rs].sum+tr[now].val;
}

bool ok(int now){
    return (tr[now].d[0]>=x1 && tr[now].d[1]>=y1 && tr[now].d[0]<=x2 && tr[now].d[1]<=y2);
}

int check(int now){
    if(tr[now].mn[0]>=x1 && tr[now].mn[1]>=y1 && tr[now].mx[0]<=x2 && tr[now].mx[1]<=y2)return 1;
    if(tr[now].mn[0]>x2 || tr[now].mn[1]>y2 || tr[now].mx[0]<x1 || tr[now].mx[1]<y1)return -1;
    return 0;
}

void query(int now){
    if(ok(now))ans+=tr[now].val;
    if(tr[now].l){
        int vis=check(tr[now].l);
        if(vis==1)ans+=tr[tr[now].l].sum;else if(vis==0)query(tr[now].l);
    }
    if(tr[now].r){
        int vis=check(tr[now].r);
        if(vis==1)ans+=tr[tr[now].r].sum;else if(vis==0)query(tr[now].r);
    }
}

int rebuild(int l,int r,int flag){
    cmpd=flag;
    int mid=(l+r)>>1;
    nth_element(tr+l+1,tr+mid+1,tr+r+1,cmp);
    tr[mid].mn[0]=tr[mid].mx[0]=tr[mid].d[0];
    tr[mid].mn[1]=tr[mid].mx[1]=tr[mid].d[1];
    tr[mid].sum=tr[mid].val;
    tr[mid].l=tr[mid].r=0;
    if(l!=mid)tr[mid].l=rebuild(l,mid-1,!flag);
    if(r!=mid)tr[mid].r=rebuild(mid+1,r,!flag);
    updata(mid);
    return mid;
}

void insert(int now){
    if(!rt){rt=now;return;}
    int p=rt,flag=0;
    while(1){
        if(tr[now].mn[0]<tr[p].mn[0])tr[p].mn[0]=tr[now].mn[0];
        if(tr[now].mn[1]<tr[p].mn[1])tr[p].mn[1]=tr[now].mn[1];
        if(tr[now].mx[0]>tr[p].mx[0])tr[p].mx[0]=tr[now].mx[0];
        if(tr[now].mx[1]>tr[p].mx[1])tr[p].mx[1]=tr[now].mx[1];
        tr[p].sum+=tr[now].sum;
        if(tr[now].d[flag]<=tr[p].d[flag]){
            if(!tr[p].l){tr[p].l=now;break;}
            else p=tr[p].l;
        }else{
            if(!tr[p].r){tr[p].r=now;break;}
            else p=tr[p].r;
        }
        flag=!flag;
    }
}

int main(){
    int cnt,typ,x,y,v;
    read(cnt);cnt=0;
    while(scanf("%d",&typ)){
        if(typ==3)break;
        if(typ==1){
            read(x);read(y);read(v);
            x^=ans;y^=ans;v^=ans;
            cnt++;
            tr[cnt].mn[0]=tr[cnt].mx[0]=tr[cnt].d[0]=x;
            tr[cnt].mn[1]=tr[cnt].mx[1]=tr[cnt].d[1]=y;
            tr[cnt].val=tr[cnt].sum=v;
            insert(cnt);
            if(cnt%10000==0)rt=rebuild(1,cnt,0);
        }
        if(typ==2){
            read(x1);read(y1);read(x2);read(y2);
            x1^=ans;y1^=ans;x2^=ans;y2^=ans;
            ans=0;
            query(rt);
            printf("%d\n",ans);
        }
    }
}

 

posted @ 2018-05-11 12:26  lnyzo  阅读(96)  评论(0编辑  收藏  举报