zoukankan      html  css  js  c++  java
  • bzoj3637: Query on a tree VI

    Description

    You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are numbered from 1 to n.

    Each node has a color, white or black. All the nodes are black initially.

    We will ask you to perfrom some instructions of the following form:

    • u : ask for how many nodes are connected to u, two nodes are connected iff all the node on the path from u to v (inclusive u and v) have a same color.
    • u : toggle the color of u(that is, from black to white, or from white to black).
     

    Input

    The first line contains a number n denoted how many nodes in the tree(1 ≤ n ≤ 105). The next n - 1 lines, each line has two numbers (u,  v) describe a edge of the tree(1 ≤ u,  v ≤ n). The next line contains a number m denoted how many operations we are going to process(1 ≤ m ≤ 105). The next m lines, each line describe a operation (t,  u) as we mentioned above(0 ≤ t ≤ 1, 1 ≤ u ≤ n).

     

    Output

     

    For each query operation, output the corresponding result.

    Sample Input

    5
    1 2
    1 3
    1 4
    1 5
    3
    0 1
    1 1
    0 1

    Sample Output

    5
    1

     题解:

    先将树定个根,然后建立黑白两棵lct

    对于黑树,时刻满足如果有边u-v,则v一定是黑点(u不一定是黑点)

    且对于黑树上的某个点,记录一下通过虚边和它相连的黑点有多少,lct上维护这条链的总和,白树同理

    对于单点改色,假如它是黑点,要在黑树上把它和它父亲节点断开,然后再在白树上把它和它父亲节点连起来,白点同理

    对于单点查询,假如它是黑点,把它access上去后要判断这条链最上面的那个点是不是黑点,不是就要输出最上面那个点的儿子节点,白点同理

    code:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 char ch;
     8 bool ok;
     9 void read(int &x){
    10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    11     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    12     if (ok) x=-x;
    13 }
    14 const int maxn=100005;
    15 const int maxm=200005;
    16 int n,q,op,a,b,tot,now[maxn],son[maxm],pre[maxm],col[maxn],fa[maxn];
    17 bool flag[maxn];
    18 struct LCT{
    19     int id,fa[maxn],son[maxn][2],tot[maxn],sum[maxn];
    20     void init(int x,int op){tot[x]+=op,sum[x]+=op;}
    21     int which(int x){return son[fa[x]][1]==x;}
    22     bool isroot(int x){return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;}
    23     void update(int x){
    24         sum[x]=tot[x];
    25         if (son[x][0]) sum[x]+=sum[son[x][0]];
    26         if (son[x][1]) sum[x]+=sum[son[x][1]];
    27     }
    28     void rotate(int x){
    29         int y=fa[x],z=fa[y],d=which(x),dd=which(y);
    30         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],fa[x]=fa[y];
    31         if (!isroot(y)) son[z][dd]=x;
    32         fa[y]=x,son[x][d^1]=y,update(y),update(x);
    33     }
    34     void splay(int x){
    35         while (!isroot(x)){
    36             if (isroot(fa[x])) rotate(x);
    37             else if (which(fa[x])==which(x)) rotate(fa[x]),rotate(x);
    38             else rotate(x),rotate(x);
    39         }
    40     }
    41     void access(int x){
    42         for (int p=0;x;x=fa[x]){
    43             splay(x);
    44             if (son[x][1]) tot[x]+=sum[son[x][1]];
    45             if (p) tot[x]-=sum[p];
    46             son[x][1]=p,update(p=x);
    47         }
    48     }
    49     void cut(int x,int y){
    50         if (!y) return;
    51         access(x),splay(x),fa[son[x][0]]=0,son[x][0]=0,update(x);
    52     }
    53     void link(int x,int y){
    54         if (!y) return;
    55         access(y),splay(y),splay(x),fa[x]=y,son[y][1]=x,update(y);
    56     }
    57     int find_left(int x){for (access(x),splay(x);son[x][0];x=son[x][0]); return x;}
    58     void query(int x){
    59         int t=find_left(x); splay(t);
    60         printf("%d
    ",col[t]==id?sum[t]:sum[son[t][1]]);
    61     }
    62 }T[2];
    63 void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
    64 void add(int a,int b){put(a,b),put(b,a);}
    65 void dfs(int u){
    66     for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    67         if (v!=fa[u]) fa[v]=u,T[1].link(v,u),dfs(v);
    68 }
    69 int main(){
    70     read(n),T[0].id=0,T[1].id=1;
    71     for (int i=1;i<n;i++) read(a),read(b),add(a,b);
    72     for (int i=1;i<=n;i++) col[i]=1;
    73     for (int i=1;i<=n;i++) T[1].init(i,1);
    74     dfs(1);
    75     for (read(q);q;q--){
    76         read(op),read(a);
    77         if (op) T[col[a]].cut(a,fa[a]),T[col[a]].init(a,-1),col[a]^=1,T[col[a]].init(a,1),T[col[a]].link(a,fa[a]);
    78         else T[col[a]].query(a);
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    网站是HTTP?10分钟变成HTTPS!域名免费添加配置SSL证书,变成https//环境
    纯JS实现在一个字符串b中查找另一个字符串a出现的所有位置,并且不使用字符串的方法(递归)
    网站怎么上传到服务器流程,从本地到服务器上线过程并通过域名(IP地址)进行访问
    html5新特性-header,nav,footer,aside,article,section等各元素的详解
    Django2.2中间件详解
    掌握使用gitlab ci构建Android包的正确方式
    回想让你最有成就感的bug是什么?你是如何发现这个bug的?
    聊聊用Selenium做自动化碰到了哪些坑?都是怎么解决的?
    关于手机淘宝3.25bug我的一些思考与建议
    用docker搭建selenium grid分布式环境实践之路
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5228875.html
Copyright © 2011-2022 走看看