BZOJ4399 : 魔法少女LJJ

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

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

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

时间复杂度$O(m\log 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\n",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\n",v[T[F(x)]]);
  }
  return 0;
}

  

posted @ 2016-01-20 01:05  Claris  阅读(851)  评论(0编辑  收藏  举报