zoukankan      html  css  js  c++  java
  • [BZOJ][Tjoi2016&Heoi2016]树

    题解:这个题有两种做法吧   不嫌麻烦就直接无脑维护子树里面深度深度最大的位置   比较简单几乎可以线性的做法就是  用并查集倒着过来维护联通  每个点所在联通快的根就是答案

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=3e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    
    typedef struct node{
        int op,x;
    }node;
    node d[MAXN];
    
    int fa[MAXN];
    int f[MAXN];
    int vis[MAXN];
    
    
    int find1(int x){
        if(x==f[x])return x;
        else return f[x]=find1(f[x]);
    }
    
    
    void dfs(int x,int pre){
        fa[x]=pre;
        if(!vis[x])f[x]=find1(f[pre]);
        link(x){
    	dfs(j->t,x);
        }
    }
    
    stack<int>s;
    int main(){
        int n=read(),m=read();
        int u,v;
        inc(i,2,n)u=read(),v=read(),add(u,v);
        char str[11];vis[1]=1;
        inc(i,1,m){
    	scanf("%s %d",str,&u);
    	if(str[0]=='Q')d[i].op=1,d[i].x=u;
    	else d[i].op=2,d[i].x=u,vis[u]++;
        }
        inc(i,1,n)f[i]=i;
        dfs(1,0);
        dec(i,m,1){
    	if(d[i].op==1)s.push(find1(d[i].x));
    	else {
    	    if(vis[d[i].x]){
    		vis[d[i].x]--;
    		if(!vis[d[i].x])f[d[i].x]=find1(fa[d[i].x]);
    	    }
    	}
        }
        while(!s.empty()){
    	printf("%d
    ",s.top());
    	s.pop();
        }
    }
    

      

    4551: [Tjoi2016&Heoi2016]树

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 2109  Solved: 1013
    [Submit][Status][Discuss]

    Description

    在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下
    两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个
    结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖
    先)你能帮帮他吗?

    Input

    输入第一行两个正整数N和Q分别表示节点个数和操作次数接下来N-1行,每行两个正整数u,v(1≤u,v≤n)表示u到v
    有一条有向边接下来Q行,形如“opernum”oper为“C”时表示这是一个标记操作,oper为“Q”时表示这是一个询
    问操作对于每次询问操作,1 ≤ N, Q ≤ 100000。

    Output

    输出一个正整数,表示结果

    Sample Input

    5 5
    1 2
    1 3
    2 4
    2 5
    Q 2
    C 2
    Q 2
    Q 5
    Q 3

    Sample Output

    1
    2
    2
    1

    HINT

     新加数据9组(By HFLSyzx ),未重测--2016.8.2

  • 相关阅读:
    javascript 自定义事件
    tf.control_dependencies
    神经网络全连接层+softmax:
    Tensorflow图级别随机数设置-tf.set_random_seed(seed)
    tensorflow-GPU配置
    python-生成器(generation)
    编码器内容-去噪
    Group Convolution组卷积
    VSCode 设置vue 保存自动格式化代码
    redis外部连接
  • 原文地址:https://www.cnblogs.com/wang9897/p/10336377.html
Copyright © 2011-2022 走看看