20pts,自己的做法,玄关
查看原帖
20pts,自己的做法,玄关
556955
123wbl楼主2024/11/11 22:26
#include<iostream>
#include<cstring>
using namespace std;
struct edge
{
    int to,next;
}e[2000001];
struct Tree
{
    int l,r,res,add;
}tree[4000001];
int n,q,head[200001],tot,id[200001],a[200001],cnt,dep[200001];
int b[200001],siz[200001],son[200001],top[200001],vis[200001];
inline void add(int u,int v)
{
    e[++tot].next=head[u];
    e[tot].to=v;
    head[u]=tot;
}
void dfs1(int u,int deep)
{
    dep[u]=deep;
    siz[u]=1;
    int maxson=-1;
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].to;
        dfs1(v,deep+1);
        siz[u]+=siz[v];
        if(siz[v]>maxson) maxson=siz[v],son[u]=v;
    }
}
void dfs2(int u,int topf)
{
    id[u]=++cnt;
    top[u]=topf;
    b[cnt]=u;
    if(son[u]) dfs2(son[u],topf);
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].to;
        if(v==son[u]) continue;
        dfs2(v,v);
    }
}
void build(int p,int l,int r)
{
    tree[p].l=l,tree[p].r=r,tree[p].add=-1;
    if(l==r)
    {
        tree[p].res=1;
        return;
    }
    int mid=(l+r)>>1;
    build(p*2,l,mid);
	build(p*2+1,mid+1,r);
    tree[p].res=max(tree[p*2].res,tree[p*2+1].res);
}
inline void pushdown(int p)
{
    if(tree[p].add==-1) return;
    if(tree[p*2].res<tree[p].add)
        tree[p*2].res=tree[p].add,tree[p*2].add=tree[p].add;
    if(tree[p*2+1].res<tree[p].add)
        tree[p*2+1].res=tree[p].add,tree[p*2+1].add=tree[p].add;
    tree[p].add=-1;
}
inline void update(int p,int x,int y,int k)
{
    int l=tree[p].l,r=tree[p].r;
    if(x<=l&&r<=y)
    {
        if(tree[p].res<k)
            tree[p].res=k,tree[p].add=k;
        return;
    }
    pushdown(p);
    int mid=(l+r)>>1;
    if(x<=mid) update(p*2,x,y,k);
    if(y>mid) update(p*2+1,x,y,k);
    tree[p].res=max(tree[p*2].res,tree[p*2+1].res);
}
int query(int p,int x,int y)
{
    int l=tree[p].l,r=tree[p].r,ans=-1;
    if(x<=l&&r<=y)
        return tree[p].res;
    pushdown(p);
    int mid=(l+r)>>1;
    if(x<=mid) ans=max(ans,query(p*2,x,y));
    if(y>mid) ans=max(ans,query(p*2+1,x,y));
    return ans;
}
int main()
{
    std::cin.tie(0)->sync_with_stdio(false);
    cin>>n>>q;
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        add(x,y);
    }
    dfs1(1,1);
    dfs2(1,1);
    build(1,1,n);
    for(int i=1;i<=q;i++)
    {
        char ch;int u;
        cin>>ch>>u;
        if(ch=='C')
            if(!vis[u])
                update(1,id[u],id[u]+siz[u]-1,id[u]),vis[u]=1;
        if(ch=='Q')
            cout<<b[query(1,id[u],id[u])]<<'\n';
    }
}
/*
5 6 
1 2 
1 3 
2 4 
2 5 
Q 2 
C 2 
Q 2 
Q 5 
Q 3
Q 1
*/

大佬们,我的思路是每次修改操作时将修改的点的子树全部取一个当前点dfs序的max,不知道这种思路行不行,不行的话求hack,可以的话求条

2024/11/11 22:26
加载中...