zoukankan      html  css  js  c++  java
  • BZOJ3290 : Theresa与数据结构

    CANCEL操作可以看作删点,X坐标可以离散化

    将询问按Z坐标差分,转化成两个求Z<=某个数的和的询问

    将操作CDQ分治

    每次将前一半的修改、后一半的查询按照Z坐标排序

    然后扫描线,每到一个询问就把所有Z<=它的修改都加入

    树状数组套Treap维护

    时间复杂度$O(nlog^3n)$

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define N 600010
    using std::sort;
    int n,m,Q,i,j,x,y,z,r,t1,t2,fin[N],L[N],li,k,q[N],t,pos[N],T,C,D,ans;
    char ch;
    struct P{
      int x1,y1,x2,y2,z,t,id;
      P(){}
      P(int _x1,int _y1,int _x2,int _y2,int _z,int _t,int _id){x1=_x1,y1=_y1,x2=_x2,y2=_y2,z=_z,t=_t,id=_id;}
    }a[N],b[N],c[N];
    struct node{
      int p,val,v,sum;node*l,*r;
      node(){val=v=sum=p=0;l=r=NULL;}
      inline void up(){sum=v+l->sum+r->sum;}
    }*blank=new(node),*bit[N],pool[N<<1],*cur=pool;
    inline void Rotatel(node*&x){node*y=x->r;x->r=y->l;x->up();y->l=x;y->up();x=y;}
    inline void Rotater(node*&x){node*y=x->l;x->l=y->r;x->up();y->r=x;y->up();x=y;}
    void Ins(node*&x){
      if(x==blank){
        x=cur++;x->val=C;x->l=x->r=blank;x->v=x->sum=D;x->p=std::rand();
        return;
      }
      x->sum+=D;
      if(C==x->val){x->v+=D;return;}
      if(C<x->val){
        Ins(x->l);
        if(x->l->p>x->p)Rotater(x);
      }else{
        Ins(x->r);
        if(x->r->p>x->p)Rotatel(x);
      }
    }
    void Ask(node*&x,int a,int b){
      if(x==blank)return;
      if(C<=a&&b<=D){ans+=x->sum;return;}
      if(C<=x->val&&x->val<=D)ans+=x->v;
      if(C<x->val)Ask(x->l,a,x->val-1);
      if(D>x->val)Ask(x->r,x->val+1,b);
    }
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline int lower(int x){
      int l=1,r=k,t,mid;
      while(l<=r)if(L[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    inline bool cmp(P a,P b){return a.z<b.z;}
    inline void add(int x){for(;x<=k;Ins(bit[x]),x+=x&-x)if(pos[x]<T)pos[x]=T,bit[x]=blank;}
    inline int sum(int x){for(ans=0;x;x-=x&-x)if(pos[x]==T)Ask(bit[x],0,10000000);return ans;}
    void solve(int l,int r){
      if(l==r)return;
      int mid=(l+r)>>1;
      solve(l,mid),solve(mid+1,r);
      for(t1=0,i=l;i<=mid;i++)if(!a[i].id)b[++t1]=a[i];
      for(t2=0,i=r;i>mid;i--)if(a[i].id)c[++t2]=a[i];
      if(!t1||!t2)return;
      sort(b+1,b+t1+1,cmp),sort(c+1,c+t2+1,cmp);
      for(T++,cur=pool,i=j=1;i<=t2;i++){
        while(j<=t1&&b[j].z<=c[i].z)C=b[j].y1,D=b[j].t,add(b[j].x1),j++;
        C=c[i].y1,D=c[i].y2,fin[c[i].id]+=c[i].t*(sum(c[i].x2)-sum(c[i].x1-1));
      }
    }
    int main(){
      blank->l=blank->r=blank;
      read(n);
      while(n--)read(x),read(y),read(z),a[++m]=P(x,y,x,y,z,1,0);
      read(n);
      for(i=1;i<=n;i++){
        while(!(((ch=getchar())=='A')||(ch=='Q')||(ch=='C')));
        if(ch=='A')read(x),read(y),read(z),a[q[++t]=++m]=P(x,y,x,y,z,1,0);
        if(ch=='C'){
          while((ch=getchar())!='L');
          a[++m]=a[q[t--]],a[m].t=-1;
        }
        if(ch=='Q')read(x),read(y),read(z),read(r),a[++m]=P(x,y,x+r,y+r,z+r,1,++Q),a[++m]=P(x,y,x+r,y+r,z-1,-1,Q);
      }
      for(i=1;i<=m;i++)L[++li]=a[i].x1,L[++li]=a[i].x2;
      sort(L+1,L+li+1);
      for(i=1;i<=li;i++)if(i==1||L[i-1]!=L[i])L[++k]=L[i];
      for(i=1;i<=m;i++)a[i].x1=lower(a[i].x1),a[i].x2=lower(a[i].x2);
      solve(1,m);
      for(i=1;i<=Q;i++)printf("%d
    ",fin[i]);
      return 0;
    }
    

      

  • 相关阅读:
    centos7 yum 方式安装nginx
    在Windows系统下用命令把应用程序添加到系统服务
    WPF内置命令
    Json解析实例
    端口占用的问题
    WPF里的报警闪烁效果
    python类中的一些神奇方法
    python中交换两个变量值的方法
    lambda应用
    python函数不定长参数
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403145.html
Copyright © 2011-2022 走看看