zoukankan      html  css  js  c++  java
  • BZOJ4399 : 魔法少女LJJ

    将所有权值离散化,建立权值线段树,维护区间内数字个数以及对数的和,用于比较乘积大小。

    对于每个连通块维护一棵权值线段树,合并时用线段树合并。

    对于操作3和4,暴力删除所有不合法节点,然后一并修改后插入线段树即可。

    时间复杂度$O(mlog m)$。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=400010,M=7000000;
    int n,m,i,x,y,op[N][3],b[N],U,f[N],T[N],cnt;
    int tot,l[M],r[M],v[M];double s[M],L[N];
    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=U,mid,t;
      while(l<=r)if(b[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    int F(int x){return f[x]==x?x:f[x]=F(f[x]);}
    void ins(int&x,int a,int b,int c,int d,double e){
      if(!x)x=++tot;
      v[x]+=d,s[x]+=e;
      if(a==b)return;
      int mid=(a+b)>>1;
      if(c<=mid)ins(l[x],a,mid,c,d,e);else ins(r[x],mid+1,b,c,d,e);
    }
    inline void up(int x){
      v[x]=v[l[x]]+v[r[x]];
      s[x]=s[l[x]]+s[r[x]];
    }
    void del(int x,int a,int b,int c,int d){
      if(!v[x])return;
      if(a==b){
        cnt+=v[x],v[x]=0,s[x]=0;
        return;
      }
      int mid=(a+b)>>1;
      if(c<=mid)del(l[x],a,mid,c,d);
      if(d>mid)del(r[x],mid+1,b,c,d);
      up(x);
    }
    int merge(int x,int y,int a,int b){
      if(!x)return y;
      if(!y)return x;
      if(a==b){
        v[x]+=v[y];
        s[x]+=s[y];
        return x;
      }
      int mid=(a+b)>>1;
      l[x]=merge(l[x],l[y],a,mid);
      r[x]=merge(r[x],r[y],mid+1,b);
      return up(x),x;
    }
    inline int kth(int x,int k){
      int a=1,b=U,mid;
      while(a<b){
        mid=(a+b)>>1;
        if(v[l[x]]>=k)b=mid,x=l[x];else k-=v[l[x]],a=mid+1,x=r[x];
      }
      return a;
    }
    int main(){
      read(m);
      for(i=1;i<=m;i++){
        read(op[i][0]),read(op[i][1]);
        if(op[i][0]>1&&op[i][0]<7)read(op[i][2]);
        if(op[i][0]==1)b[++U]=op[i][1];
        if(op[i][0]==3||op[i][0]==4)b[++U]=op[i][2];
      }
      sort(b+1,b+U+1);
      for(i=1;i<=U;i++)L[i]=log(b[i]);
      for(i=1;i<=m;i++){
        x=op[i][1],y=op[i][2];
        if(op[i][0]==1){
          x=lower(x),n++;
          f[n]=n,ins(T[n],1,U,x,1,L[x]);
        }
        if(op[i][0]==2){
          x=F(x),y=F(y);
          if(x==y)continue;
          T[f[x]=y]=merge(T[x],T[y],1,U);
        }
        if(op[i][0]==3){
          x=F(x),y=lower(y),cnt=0;
          if(y>1)del(T[x],1,U,1,y-1);
          if(cnt)ins(T[x],1,U,y,cnt,L[y]*cnt);
        }
        if(op[i][0]==4){
          x=F(x),y=lower(y),cnt=0;
          if(y<U)del(T[x],1,U,y+1,U);
          if(cnt)ins(T[x],1,U,y,cnt,L[y]*cnt);
        }
        if(op[i][0]==5)printf("%d
    ",b[kth(T[F(x)],y)]);
        if(op[i][0]==6)puts(s[T[F(x)]]>s[T[F(y)]]?"1":"0");
        if(op[i][0]==7)printf("%d
    ",v[T[F(x)]]);
      }
      return 0;
    }
    

      

  • 相关阅读:
    高性能MySQL学习总结二----常见数据类型选择及优化
    springboot admin图文+视频教程
    xxl-job图文教程+视频讲解
    mybatis-plus视频教程
    springcloud视频教程
    springcloud系统化学习图文+视频教程
    docker系统化学习图文+视频教程
    【分享】docker全套视频教程
    是用Git还是SVN?
    NOIP知识点汇总
  • 原文地址:https://www.cnblogs.com/clrs97/p/5143907.html
Copyright © 2011-2022 走看看