zoukankan      html  css  js  c++  java
  • BZOJ4046 : [Cerc2014] Pork barre

    按边权从大到小加边,用Link-Cut Tree维护最小生成树。

    对于当前要加的边i,最小生成树上边权在[1,R]范围内的和就是询问[e[i].w,R]的答案。

    因为强制在线,所以用主席树存下所有历史版本即可。时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=101010,M=3600010;
    struct edge{int x,y,w;}e[N];
    inline bool cmp(edge a,edge b){return a.w>b.w;}
    int T,n,m,q,i,j,x,y,ans,root[N],l[M],r[M],v[M],tot;
    int f[N],son[N][2],val[N],sum[N],from[N],tmp[N],fa[N];bool rev[N];
    int ins(int x,int a,int b,int c,int d){
      int y=++tot;
      v[y]=v[x]+d,l[y]=l[x],r[y]=r[x];
      if(a==b)return y;
      int mid=(a+b)>>1;
      if(c<=mid)l[y]=ins(l[x],a,mid,c,d);else r[y]=ins(r[x],mid+1,b,c,d);
      return y;
    }
    int ask(int x,int a,int b,int c,int d){
      if(!x||c>d)return 0;
      if(c<=a&&b<=d)return v[x];
      int mid=(a+b)>>1,t=0;
      if(c<=mid)t=ask(l[x],a,mid,c,d);
      if(d>mid)t+=ask(r[x],mid+1,b,c,d);
      return t;
    }
    inline bool isroot(int x){return !f[x]||(son[f[x]][0]!=x&&son[f[x]][1]!=x);}
    inline void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;}
    inline void pb(int x){if(rev[x])rev1(son[x][0]),rev1(son[x][1]),rev[x]=0;}
    inline void up(int x){
      sum[x]=val[x],from[x]=x;
      if(son[x][0])if(sum[son[x][0]]>sum[x])sum[x]=sum[son[x][0]],from[x]=from[son[x][0]];
      if(son[x][1])if(sum[son[x][1]]>sum[x])sum[x]=sum[son[x][1]],from[x]=from[son[x][1]];
    }
    inline void rotate(int x){
      int y=f[x],w=son[y][1]==x;
      son[y][w]=son[x][w^1];
      if(son[x][w^1])f[son[x][w^1]]=y;
      if(f[y]){
        int z=f[y];
        if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
      }
      f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
    }
    inline void splay(int x){
      int s=1,i=x,y;tmp[1]=i;
      while(!isroot(i))tmp[++s]=i=f[i];
      while(s)pb(tmp[s--]);
      while(!isroot(x)){
        y=f[x];
        if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
        rotate(x);
      }
      up(x);
    }
    inline void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y,up(x);}
    inline void makeroot(int x){access(x);splay(x);rev1(x);}
    inline void link(int x,int y){makeroot(x);f[x]=y;access(x);}
    inline void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;up(x);}
    inline void cut(int x,int y){makeroot(x);cutf(y);}
    inline int askfrom(int x,int y){makeroot(x);access(y);splay(y);return from[y];}
    int F(int x){return fa[x]==x?x:fa[x]=F(fa[x]);}
    inline int lower(int x){
      int l=1,r=m,mid,t=0;
      while(l<=r)if(e[mid=(l+r)>>1].w<=x)r=(t=mid)-1;else l=mid+1;
      return t;
    }
    inline int getid(int x){
      int l=1,r=m,mid,t=0;
      while(l<=r)if(e[mid=(l+r)>>1].w>=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    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';}
    int main(){
      read(T);
      while(T--){
        read(n),read(m);
        for(i=1;i<=n;i++)fa[i]=i;
        for(i=1;i<=m;i++)read(e[i].x),read(e[i].y),read(e[i].w);
        sort(e+1,e+m+1,cmp);
        for(i=1;i<=m;i++)val[n+i]=sum[n+i]=e[i].w,from[n+i]=n+i;
        for(i=1;i<=m;i++){
          root[i]=root[i-1];
          if(F(e[i].x)==F(e[i].y)){
            j=askfrom(e[i].x,e[i].y);
            cut(j,e[j-n].x),cut(j,e[j-n].y);
            root[i]=ins(root[i],1,m,j-n,-e[j-n].w);
          }else fa[fa[e[i].x]]=fa[e[i].y];
          link(e[i].x,n+i),link(e[i].y,n+i);
          root[i]=ins(root[i],1,m,i,e[i].w);
        }
        read(q);
        while(q--){
          read(x),read(y),x-=ans,y-=ans;
          printf("%d
    ",ans=ask(root[getid(x)],1,m,lower(y),m));
        }
        for(i=tot=ans=0;i<=n+m;i++)f[i]=son[i][0]=son[i][1]=val[i]=sum[i]=from[i]=rev[i]=0;
        for(i=1;i<=n;i++)fa[i]=0;
        for(i=1;i<=m;i++)root[i]=0;
      }
      return 0;
    }
    

      

  • 相关阅读:
    javascript 日期月份加减
    ActiveRecord 的类型初始值设定项引发异常
    angularjs $q、$http 处理多个异步请求
    angular.foreach 格式
    PHP基础知识2
    第一个月的学习总结
    JavaScript的学习5
    JavaScript的学习4
    JavaScript的学习3
    JavaScript的学习2
  • 原文地址:https://www.cnblogs.com/clrs97/p/4690629.html
Copyright © 2011-2022 走看看