zoukankan      html  css  js  c++  java
  • bzoj3784: 树上的路径

    题解:

    点分治序列+超级钢琴那题

    搞出点分治序列

    那么每个点能构成路径的就是连续的一段

    上次是用线段树维护的。。这次就用st表了

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define IL inline
    #define rint register int
    #define me(x) memset(x,0,sizeof(x))
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    #define mid ((h+t)/2)
    char ss[1<<24],*A=ss,*B=ss;
    char gc()
    {
      return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; 
    }
    template<class T> void read(T &x)
    {
      rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=c^48;
      while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
    }
    const int INF=1e9;
    const int N=6e5+10;
    const int N2=1e8;
    struct re{
      int a,b,c;
    }a[N];
    struct re1{
      int a,b,c,d,e;
    };
    struct cmp{
      bool operator() (re1 x,re1 y)
      {
        return(x.a<y.a);
      }
    };
    priority_queue<re1,vector<re1>,cmp> Q;
    int head[N],l,n,m,rt,son[N],f[N],cnt,sum,d[N];
    int s[N2],t[N2],p[N2];
    bool vis[N];
    IL void arr(int x,int y,int z)
    {
      a[++l].a=head[x];
      a[l].b=y;
      a[l].c=z;
      head[x]=l;
    }
    void gr(int x,int fa)
    {
      son[x]=1;f[x]=0;
      int u=head[x];
      while (u)
      {
        int v=a[u].b;
        if (vis[v]&&v!=fa)
        {
          gr(v,x);
          son[x]+=son[v];
          f[x]=max(f[x],son[v]);
        }
        u=a[u].a;
      }
      f[x]=max(f[x],sum-son[x]);
      if(f[x]<f[rt]) rt=x;
    }
    void gd(int x,int fa,int bg,int ed,int z)
    {
      int u=head[x];
      while (u)
      {
        int v=a[u].b;
        if (vis[v]&&v!=fa)
        {
          d[v]=d[x]+a[u].c;
          p[++cnt]=d[v];
          if (x==z)
          {
            s[cnt]=bg; t[cnt]=cnt-1; 
            gd(v,x,bg,cnt-1,z); 
          } else
          {
            s[cnt]=bg; t[cnt]=ed; 
            gd(v,x,bg,ed,z);
          }
        }
        u=a[u].a;
      }
    }
    int num;
    void solve(int x,int y)
    {
      int u=head[x];
      vis[x]=0; int bg=cnt+1;
      d[x]=0; 
      gd(x,0,bg,0,x);
      p[++cnt]=0; s[cnt]=bg; t[cnt]=cnt-1;
      while (u)
      {
        int v=a[u].b;
        if (vis[v])
        {
          rt=0; sum=son[v];
          gr(v,x);
          solve(rt,y+1);
        }
        u=a[u].a;
      }
    }
    int bz[20][N],bz2[20][N]; 
    IL re query(int x,int y)
    {
      int z=log2(y-x+1);
      if (bz[z][x]>bz[z][y-(1<<z)+1])
        return((re){bz2[z][x],bz[z][x]});
      else return((re){bz2[z][y-(1<<z)+1],bz[z][y-(1<<z)+1]});
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      read(n); read(m);
      rep(i,1,n-1)
      {
        int x,y,z;
        read(x); read(y); read(z);
        arr(x,y,z); arr(y,x,z);
      }
      memset(vis,1,sizeof(vis));
      f[0]=INF;
      sum=n; gr(1,0); 
      solve(rt,0);
      rep(i,1,cnt) bz[0][i]=p[i],bz2[0][i]=i;
      rep(i,1,16)
        rep(j,1,cnt) 
          if (bz[i-1][j]>bz[i-1][j+(1<<(i-1))]) 
            bz[i][j]=bz[i-1][j],bz2[i][j]=bz2[i-1][j];
          else bz[i][j]=bz[i-1][j+(1<<(i-1))],bz2[i][j]=bz2[i-1][j+(1<<(i-1))];
      rep(i,1,cnt)
      {
        if (s[i]<=t[i])
        {
          re xx=query(s[i],t[i]);
          int x=xx.a,y=xx.b;
          Q.push((re1){p[i]+y,i,s[i],t[i],x});
        }
      }
      int ans;
      rep(i,1,m)
      {
        re1 xx=Q.top(); Q.pop();
        ans=xx.a;
        int j=xx.b;
        if (xx.c<xx.e)
        {
          re z=query(xx.c,xx.e-1);
          int x=z.a,y=z.b;
          Q.push((re1){p[j]+y,j,xx.c,xx.e-1,x});
        }
        if (xx.e<xx.d)
        {
          re z=query(xx.e+1,xx.d);
          int x=z.a,y=z.b;
          Q.push((re1){p[j]+y,j,xx.e+1,xx.d,x});
        }
        cout<<ans<<endl;
      }
      return 0; 
    }

     

  • 相关阅读:
    nrm安装与配置(nrm管理npm源)
    Mac启动MongoDB报错:exception in initAndListen: NonExistentPath: Data directory /data/db not found., terminating
    基本类型(例如:int)数组和ArrayList之间的转化
    sqlite3--sqlite3_prepare
    fgets
    strdup
    openssl-EVP_md5()
    FIPS--Federal Information Processing Standards
    pthread_mutexattr_gettype、pthread_mutexattr_settype、pthread_mutexattr_destroy、pthread_mutexattr_init!
    gethostname&&getdomainname
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9302505.html
Copyright © 2011-2022 走看看