P4092 [HEOI2016/TJOI2016] 树

P4092 [HEOI2016/TJOI2016] 树

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

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

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

你能帮帮她吗?

提示

\(100\%\) 的数据,\(1 \leqslant N, Q \leqslant 100000\)

Solution:

十分好写的题目,我们考虑点亮一个点会带来的影响,显然,点亮一个点只会对其子树产生影响,所以我们先求出这颗子树上的 dfs序 然后记录一下每个点的子树下的 dfs序范围 \([st_x,ed_x]\) . 然后我们就可以按照 dfs序 建一颗线段树。维护一下每个 dfs序区间 的点亮过的点中 dfs序的最大值 ,区间修改单点查询。

然后这题就做完了 。

Code:

#include<bits/stdc++.h>
const int N=1e5+5;
using namespace std;
struct Segmnet_Tree{
    struct Tree{
        int val;
    }t[N<<2];
    #define ls x<<1
    #define rs x<<1|1
    void pushup(int x)
    {
        t[x].val=max(t[ls].val,t[rs].val);
    }
    void upd(int x,int l,int r,int L,int R,int k)
    {
        if(L<=l&&r<=R)
        {
            t[x].val=max(t[x].val,k);return;
        }
        int mid=l+r>>1;
        if(L<=mid)upd(ls,l,mid,L,R,k);
        if(mid<R)upd(rs,mid+1,r,L,R,k);
    }
    void query(int x,int l,int r,int pos,int &res)
    {
        res=max(res,t[x].val);
        if(l==r)return;
        int mid=l+r>>1;
        if(pos<=mid)query(ls,l,mid,pos,res);
        else query(rs,mid+1,r,pos,res);
    }
}T;
vector<int> E[N];
int n,m,tot;
int rid[N],st[N],ed[N];
void dfs(int x,int fa)
{
    st[x]=++tot;rid[tot]=x;
    for(auto y : E[x])if(y!=fa)
    {
        dfs(y,x);
    }
    ed[x]=tot;
}
char c[10];
void work()
{
    cin>>n>>m;
    for(int i=2,x,y;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        E[x].push_back(y);E[y].push_back(x);
    }
    dfs(1,0);
    T.upd(1,1,n,1,n,1);
    for(int i=1,x;i<=m;i++)
    {
        scanf("%s",c);scanf("%d",&x);
        if(c[0]=='C')
        {
            T.upd(1,1,n,st[x],ed[x],st[x]);
        }
        else
        {
            int res=0;
            T.query(1,1,n,st[x],res);
            printf("%d\n",rid[res]);
        }
    }
}
int main()
{
    //freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);
    work();
    return 0;
}
posted @ 2025-02-07 18:42  liuboom  阅读(14)  评论(0)    收藏  举报