多维维护问题,每层换一维进行统计。

 

bzoj4066 简单题

题目大意:给(x,y)+A,求(x1,y1)~(x2,y2)的权值和。

思路:kd-tree,但这道题目中重建是特判的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200005
using namespace std;
inline int in(){
    char ch=getchar();int x=0;
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x;}
int dd,rt,tt=0;
struct use{
    int d[2],mn[2],mx[2],sm,v,l,r;
    int &operator[](int x){return d[x];}
    bool operator==(const use&x)const{return d[0]==x.d[0]&&d[1]==x.d[1];}
    bool operator<(const use &x)const{return d[dd]<x.d[dd];}
}tr[N],nt,ci[N];
inline bool bin(int x1,int y1,int x2,int y2,int a1,int b1,int a2,int b2){
    return x1<=a1&&y1<=b1&&x2>=a2&&y2>=b2;
}
inline bool bout(int x1,int y1,int x2,int y2,int a1,int b1,int a2,int b2){
    return x1>a2||x2<a1||y1>b2||y2<b1;
}
void updata(int x){
    int i,l,r;l=tr[x].l;r=tr[x].r;
    for (i=0;i<2;++i){
        tr[x].mn[i]=tr[x].mx[i]=tr[x][i];
        if (l){
            tr[x].mn[i]=min(tr[x].mn[i],tr[l].mn[i]);
            tr[x].mx[i]=max(tr[x].mx[i],tr[l].mx[i]);
        }if (r){
            tr[x].mn[i]=min(tr[x].mn[i],tr[r].mn[i]);
            tr[x].mx[i]=max(tr[x].mx[i],tr[r].mx[i]);
        }
    }tr[x].sm=tr[x].v+tr[l].sm+tr[r].sm;}
void ins(int &x,int d){
    if (!x){x=++tt;tr[x]=nt;return;}
    if (tr[x]==nt){tr[x].v+=nt.v;tr[x].sm+=nt.v;return;}
    if (nt[d]<tr[x][d]) ins(tr[x].l,d^1);
    else ins(tr[x].r,d^1);
    updata(x);
}
int query(int x,int d,int x1,int y1,int x2,int y2){
    if (!x) return 0;
    if (bin(x1,y1,x2,y2,tr[x].mn[0],tr[x].mn[1],tr[x].mx[0],tr[x].mx[1])) return tr[x].sm;
    if (bout(x1,y1,x2,y2,tr[x].mn[0],tr[x].mn[1],tr[x].mx[0],tr[x].mx[1])) return 0;
    int sm=0;
    if (bin(x1,y1,x2,y2,tr[x][0],tr[x][1],tr[x][0],tr[x][1])) sm+=tr[x].v;
    sm+=query(tr[x].l,d^1,x1,y1,x2,y2)+query(tr[x].r,d^1,x1,y1,x2,y2);
    return sm;}
int rebuild(int l,int r,int d){
    if (l>r) return 0;
    int mid=(l+r)>>1;
    dd=d;nth_element(ci+l,ci+mid,ci+r+1);
    tr[mid]=ci[mid];
    tr[mid].l=rebuild(l,mid-1,d^1);
    tr[mid].r=rebuild(mid+1,r,d^1);
    updata(mid);return mid;}
int main(){
    int op,x1,y1,x2,y2,v,i,la=0,m=10000;
    op=in();tr[0]=(use){0,0,0,0,0,0,0,0,0,0};
    while((op=in())!=3){
        if (op==1){
            x1=in()^la;y1=in()^la;v=in()^la;
            nt=(use){x1,y1,x1,y1,x1,y1,v,v,0,0};
            ins(rt,0);
            if (tt==m){
                for (i=1;i<=tt;++i) ci[i]=tr[i];
                rt=rebuild(1,tt,0);m+=10000;
            }
        }else{
            x1=in()^la;y1=in()^la;x2=in()^la;y2=in()^la;
            la=query(rt,0,x1,y1,x2,y2);
            printf("%d\n",la);
        }
    }
}
View Code

相关文章: