zoukankan      html  css  js  c++  java
  • 【BZOJ4551】树

    题面

    在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作:

    1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个结点,可以打多次标记。)

    2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖先)

    你能帮帮他吗?

    30%的数据,1 ≤ N, Q ≤ 1000

    70%的数据,1 ≤ N, Q ≤ 10000

    100%的数据,1 ≤ N, Q ≤ 100000

    分析

    法一:树剖,线段树维护最右端的结点。

    法二:并查集,离线倒着做,相当于清除标记。当此点被标记后,显然最近的点是自己。将它与父亲的联系切断。把自己记为父亲

    如果标记被完全清除(因为可能重复标记),就和它父亲连在一起,说明这一段都是空的,可以直接忽略跳过。

    查询答案就查询祖先

    代码

    1. #include<iostream>  
    2. #include<cstdio>  
    3. #define N 100010  
    4. using namespace std;  
    5. int f[N],fa[N],v[N],ans[N],first[N],x,y,n,m,cnt;  
    6. struct email  
    7. {  
    8.     int u,v;  
    9.     int nxt;  
    10. }e[N*4];  
    11. struct use{int x,kind;}q[N];  
    12. char ch[5];  
    13. void add(int u,int v)  
    14. {  
    15.   e[++cnt].nxt=first[u];first[u]=cnt;  
    16.   e[cnt].u=u;e[cnt].v=v;  
    17. }  
    18. int find(int x){return x==f[x]?x:f[x]=find(f[x]);}  
    19. void dfs(int u)  
    20. {  
    21.     if(v[u]) f[u]=u;  
    22.     else f[u]=fa[u];  
    23.     for(int i=first[u];i;i=e[i].nxt)  
    24.     {  
    25.         int v=e[i].v;  
    26.         if (v!=fa[u]){fa[v]=u;dfs(v);}  
    27.     }      
    28. }  
    29. int main(){  
    30.     scanf("%d%d",&n,&m);  
    31.     for (int i=1;i<n;i++)  
    32.     {  
    33.         scanf("%d%d",&x,&y);  
    34.         add(x,y);add(y,x);  
    35.     }   
    36.     for(int i=1;i<=m;i++)  
    37.     {  
    38.         scanf("%s%d",&ch,&q[i].x);  
    39.         if (ch[0]=='C'){v[q[i].x]++;q[i].kind=1;}  
    40.     }  
    41.     v[1]++;dfs(1);  
    42.     for (int i=m;i>=1;i--)  
    43.     {  
    44.         if (q[i].kind)  
    45.         {  
    46.             v[q[i].x]--;  
    47.             if (v[q[i].x]==0)f[q[i].x]=fa[q[i].x];  
    48.         }  
    49.         else ans[i]=find(q[i].x);  
    50.     }  
    51.     for(int i=1;i<=m;i++)if(!q[i].kind)printf("%d ",ans[i]);  
    52. }  
  • 相关阅读:
    大数据之路Week08_day02 (Flume架构介绍和安装)
    Hive调优
    hive的shell用法(脑子糊涂了,对着脚本第一行是 #!/bin/sh 疯狂执行hive -f 结果报错)
    Week08_day01 (Hive 自定义函数 UDF 一个输入,一个输出(最常用))
    Week08_day01 (Hive开窗函数 row_number()的使用 (求出所有薪水前两名的部门))
    Week08_day01 (Hive实现按照指定格式输出每七天的消费平均数)
    Week08_day01 (Hive实现WordCount计数)
    SQL中 count(*)和count(1)的对比,区别
    大数据之路week07--day07 (修改mysql默认编码)
    10进制转换成16进制的函数(自写函数模板)
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9833320.html
Copyright © 2011-2022 走看看