zoukankan      html  css  js  c++  java
  • Hdu 2475-Box LCT,动态树

    Box

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2813    Accepted Submission(s): 821


    Problem Description
    There are N boxes on the ground, which are labeled by numbers from 1 to N. The boxes are magical, the size of each one can be enlarged or reduced arbitrarily.
    Jack can perform the “MOVE x y” operation to the boxes: take out box x; if y = 0, put it on the ground; Otherwise, put it inside box y. All the boxes inside box x remain the same. It is possible that an operation is illegal, that is, if box y is contained (directly or indirectly) by box x, or if y is equal to x.
    In the following picture, box 2 and 4 are directly inside box 6, box 3 is directly inside box 4, box 5 is directly inside box 1, box 1 and 6 are on the ground.

    The picture below shows the state after Jack performs “MOVE 4 1”:

    Then he performs “MOVE 3 0”, the state becomes:

    During a sequence of MOVE operations, Jack wants to know the root box of a specified box. The root box of box x is defined as the most outside box which contains box x. In the last picture, the root box of box 5 is box 1, and box 3’s root box is itself.
     
    Input
    Input contains several test cases.
    For each test case, the first line has an integer N (1 <= N <= 50000), representing the number of boxes.
    Next line has N integers: a1, a2, a3, ... , aN (0 <= ai <= N), describing the initial state of the boxes. If ai is 0, box i is on the ground, it is not contained by any box; Otherwise, box i is directly inside box ai. It is guaranteed that the input state is always correct (No loop exists).
    Next line has an integer M (1 <= M <= 100000), representing the number of MOVE operations and queries.
    On the next M lines, each line contains a MOVE operation or a query:
    1.  MOVE x y, 1 <= x <= N, 0 <= y <= N, which is described above. If an operation is illegal, just ignore it.
    2.  QUERY x, 1 <= x <= N, output the root box of box x.
     
    Output
    For each query, output the result on a single line. Use a blank line to separate each test case.
     
    Sample Input
    2 0 1 5 QUERY 1 QUERY 2 MOVE 2 0 MOVE 1 2 QUERY 1 6 0 6 4 6 1 0 4 MOVE 4 1 QUERY 3 MOVE 1 4 QUERY 1
     
    Sample Output
    1 1 2 1 1
     
    Source
     
    Recommend
    lcy
     
    题解:
    LCT关于子树的问题。
    判断y是否在x的子树中特别。。。
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define MAXN 50010
      4 struct node
      5 {
      6     int left,right;
      7 }tree[MAXN];
      8 int father[MAXN],rev[MAXN],Stack[MAXN],cc[MAXN];
      9 int read()
     10 {
     11     int s=0,fh=1;char ch=getchar();
     12     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     13     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     14     return s*fh;
     15 }
     16 int isroot(int x)
     17 {
     18     return tree[father[x]].left!=x&&tree[father[x]].right!=x;
     19 }
     20 void pushdown(int x)
     21 {
     22     int l=tree[x].left,r=tree[x].right;
     23     if(rev[x]!=0)
     24     {
     25         rev[x]^=1;rev[l]^=1;rev[r]^=1;
     26         swap(tree[x].left,tree[x].right);
     27     }
     28 }
     29 void rotate(int x)
     30 {
     31     int y=father[x],z=father[y];
     32     if(!isroot(y))
     33     {
     34         if(tree[z].left==y)tree[z].left=x;
     35         else tree[z].right=x;
     36     }
     37     if(tree[y].left==x)
     38     {
     39         father[x]=z;father[y]=x;tree[y].left=tree[x].right;tree[x].right=y;father[tree[y].left]=y;
     40     }
     41     else
     42     {
     43         father[x]=z;father[y]=x;tree[y].right=tree[x].left;tree[x].left=y;father[tree[y].right]=y;
     44     }
     45 }
     46 void splay(int x)
     47 {
     48     int top=0,y,z,i;Stack[++top]=x;
     49     for(i=x;!isroot(i);i=father[i])Stack[++top]=father[i];
     50     for(i=top;i>=1;i--)pushdown(Stack[i]);
     51     while(!isroot(x))
     52     {
     53         y=father[x];z=father[y];
     54         if(!isroot(y))
     55         {
     56             if((tree[y].left==x)^(tree[z].left==y))rotate(x);
     57             else rotate(y);
     58         }
     59         rotate(x);
     60     }
     61 }
     62 void access(int x)
     63 {
     64     int last=0;
     65     while(x!=0)
     66     {
     67         splay(x);
     68         tree[x].right=last;
     69         last=x;x=father[x];
     70     }
     71 }
     72 void makeroot(int x)
     73 {
     74     access(x);splay(x);rev[x]^=1;
     75 }
     76 void link(int u,int v)
     77 {
     78     makeroot(u);/*access(u);*/father[u]=v;splay(u);//////////////
     79 }
     80 void cut(int u,int v)
     81 {
     82     /*makeroot(u);*//*access(u);*/access(u);splay(u);father[tree[u].left]=0;tree[u].left=0;
     83 }
     84 int findroot(int x)
     85 {
     86     access(x);splay(x);
     87     while(tree[x].left!=0)x=tree[x].left;
     88     return x;
     89 }
     90 int Findroot(int u,int v)
     91 {
     92     /*access(v);splay(v);*/access(v);splay(u);
     93     while(tree[u].right!=0)u=tree[u].right;
     94     if(u==v)return 1;
     95     return 0;
     96 }
     97 int main()
     98 {
     99     int n,i,m,k,x,y,a,tt=0;
    100     char fh[30];
    101     while(scanf("%d",&n)!=EOF)
    102     {
    103         if(tt)puts("");
    104         tt++;
    105         for(i=1;i<=n;i++)
    106         {
    107             tree[i].left=tree[i].right=father[i]=rev[i]=cc[i]=0;
    108         }
    109         for(i=1;i<=n;i++)
    110         {
    111             a=read();
    112             if(a!=0)
    113             {
    114                 link(i,a);
    115                 //cc[i]=a;
    116             }
    117         }
    118         m=read();
    119         for(i=1;i<=m;i++)
    120         {
    121             scanf("
    %s",fh);
    122             if(fh[0]=='Q')
    123             {
    124                 k=read();
    125                 printf("%d
    ",findroot(k));
    126             }
    127             else
    128             {
    129                 x=read();y=read();
    130                 if(y==0)cut(x,y);
    131                 else if(x!=y)
    132                 {
    133                     if(Findroot(x,y)==1)continue;
    134                     cut(x,y);link(x,y);
    135                     /*access(y);splay(x);
    136                     int t=x;
    137                     while(tree[t].right!=0)t=tree[t].right;
    138                     if(t!=y){cut(x,y);link(x,y);}*/
    139                 }
    140                 /*if(x!=0&&y!=0)
    141                 {
    142                     if(Findroot(y,x)==1)continue;
    143                 }
    144                 if(cc[x]!=0)
    145                 {
    146                     cut(x,cc[x]);
    147                     //access(x);access(cc[x]);splay(cc[x]);father[tree[cc[x]].left]=0;tree[cc[x]].left=0;splay(cc[x]);//father[x]=tree[cc[x]].left=0;
    148                 }
    149                 cc[x]=y;
    150                 if(cc[x]!=0)
    151                 {
    152                     //link(x,cc[x]);
    153                     access(x);father[x]=cc[x];//splay(x);
    154                 }*/
    155             }
    156         }
    157         //printf("
    ");
    158     }
    159     return 0;
    160 }
    View Code
  • 相关阅读:
    微信小程序登录方案
    React编写input组件传参共用onChange
    webpack3+node+react+babel实现热加载(hmr)
    Nodejs 复制文件/文件夹
    MongoDB安全策略
    Mongodb启动&关闭
    Mongodb安装启动详解
    网页3D效果库Three.js学习[二]-了解照相机
    网页3D效果库Three.js初窥
    设置input标签placeholder字体颜色
  • 原文地址:https://www.cnblogs.com/Var123/p/5294244.html
Copyright © 2011-2022 走看看