SPOJ QTREE2

SPOJ QTREE2

题意:
给你一棵N个点的树要求支持两种操作:
DIST a b   求a到b路径距离
KTH a b k 求a到b路径上的第k个节点

做法:
还是动态树..跟QTREE本质没什么差别
对于DIST 两次拉实然后求两段的Sum
KTH便是两次拉实后分情况讨论(在左边还是右边还是正好那个LCA)

PS:
如果本题改成求a到b路径上第k大的数字,那便是CTSC难度的了。。(network)

  1 #include  < cstdio >
  2 #include  < cstring >
  3 #define  n 100005
  4 struct  Tsplay
  5 {
  6    #define Par(x)    (T[x].p)
  7    #define Lch(x)    (T[x].l)
  8    #define Rch(x)    (T[x].r)
  9    #define Val(x)    (T[x].val)
 10    #define Sum(x)    (T[x].sum)
 11    #define Size(x)    (T[x].size)
 12    #define Root(x)    (Lch(Par(x))!=x&&Rch(Par(x))!=x)
 13    int l,r,p;
 14    int val,sum,size;
 15}
    T[n];
 16 int  vtx[ 200005 ],w[ 200005 ],ne[ 200005 ],L[n],q[n],tot,N;
 17 bool  vis[n];
 18 char  cmd[ 1005 ];
 19 inline  void  Ins( int  u, int  v, int  ww)
 20 {
 21    vtx[++tot]=v;w[tot]=ww;ne[tot]=L[u];L[u]=tot;
 22}

 23 inline  void  BuildTree()
 24 {
 25    memset(vis,0,sizeof(vis));
 26    vis[q[1]=1]=1;
 27    for (int h=1,t=1,u=q[1];h<=t;u=q[++h])
 28    for (int p=L[u],v=vtx[p];p;v=vtx[p=ne[p]])
 29    if (!vis[v])    Par(v)=u,Size(v)=1,Val(v)=w[p],vis[q[++t]=v]=1;
 30}

 31 inline  int  Findkth( int  root, int  k)
 32 {
 33    for (int p=root;;)
 34    if (k<=Size(Lch(p)))    p=Lch(p);
 35    else
 36    if (k<=Size(Lch(p))+1)    return p;
 37    else    k-=Size(Lch(p))+1,p=Rch(p);
 38}

 39 inline  void  Tupdate( int  x)
 40 {
 41    Size(x)=Size(Lch(x))+1+Size(Rch(x));
 42    Sum(x)=Val(x);
 43    if (Lch(x))    Sum(x)+=Sum(Lch(x));
 44    if (Rch(x))    Sum(x)+=Sum(Rch(x));
 45}

 46 inline  void  zig( int  x)
 47 {
 48    int y=Par(x),z=Par(y);
 49    Lch(y)=Rch(x),Par(Lch(y))=Rch(x)=y;
 50    if (Lch(z)==y)    Lch(z)=x;
 51    else
 52    if (Rch(z)==y)    Rch(z)=x;
 53    Par(x)=z,Par(y)=x;
 54    Tupdate(y);
 55}

 56 inline  void  zag( int  x)
 57 {
 58    int y=Par(x),z=Par(y);
 59    Rch(y)=Lch(x),Par(Rch(y))=Lch(x)=y;
 60    if (Lch(z)==y)    Lch(z)=x;
 61    else
 62    if (Rch(z)==y)    Rch(z)=x;
 63    Par(x)=z,Par(y)=x;
 64    Tupdate(y);
 65}

 66 inline  void  splay( int  x)
 67 {
 68    for (int y,z;!Root(x);)
 69    {
 70        y=Par(x),z=Par(y);
 71        if (Root(y))
 72            if (Lch(y)==x)    zig(x);
 73            else    zag(x);
 74        else
 75        if (Lch(z)==y)
 76            if (Lch(y)==x)    zig(y),zig(x);
 77            else    zag(x),zig(x);
 78        else
 79            if (Rch(y)==x)    zag(y),zag(x);
 80            else    zig(x),zag(x);
 81    }

 82    Tupdate(x);
 83}

 84 inline  void  Expose( int  x)
 85 {
 86    for (int u=x,v=0;u;u=Par(u))
 87        splay(u),Rch(u)=v,Tupdate(v=u);
 88}

 89 inline  void  Query( int  x, int  y, int  k)
 90 {
 91    Expose(y);
 92    for (int u=x,v=0;u;u=Par(u))
 93    {
 94        if (splay(u),!Par(u))
 95        {
 96            if (!k)    printf("%d\n",Sum(Rch(u))+Sum(v));
 97            else
 98            if (k<=Size(v))    printf("%d\n",Findkth(v,Size(v)-k+1));
 99            else
100            if (k<=Size(v)+1)    printf("%d\n",u);
101            else    printf("%d\n",Findkth(Rch(u),k-Size(v)-1));
102            return;
103        }

104        Rch(u)=v,Tupdate(v=u);
105    }

106}

107 int  main()
108 {
109    int Te,x,y,w,k;
110    for (scanf("%d",&Te);Te--;)
111    {
112        memset(L,0,sizeof(L));
113        tot=0;
114        scanf("%d",&N);
115        for (int i=0;i<=N;++i)
116            Par(i)=Lch(i)=Rch(i)=0;
117        for (int i=1;i<N;++i)
118        {
119            scanf("%d%d%d",&x,&y,&w);
120            Ins(x,y,w),Ins(y,x,w);
121        }

122        BuildTree();
123        for (;;)
124        {
125            scanf("%s",cmd);
126            if (cmd[1]=='O')    break;
127            scanf("%d%d",&x,&y);
128            if (cmd[0]=='D')    Query(x,y,0);
129            else    scanf("%d",&k),Query(x,y,k);
130        }

131    }

132    return 0;
133}

134


 

你可能感兴趣的:(SPOJ QTREE2)