nove.20 Qtree3 (树剖好题)

https://www.luogu.com.cn/problem/P4116

思考了一下不用树剖怎么做
比如用DFS序,但查询容易,修改困难
还是回到树剖

树剖的话就很裸了

初想法:
维护区间中最浅的黑点,全是白点区间赋值-1
不知道为啥写炸了
此种想法比较低端,确实容易写炸,果断放弃

(扒大佬博客)
观察所求黑点的性质:求最浅的黑点,也就是求节点到根的路径上DFS序最小的黑点
白点权值赋极大值,黑点权值为DFS序,维护区间最小DFS序,问题转化为求区间最小值
容易实现

一发过

#include<bits/stdc++.h>
using namespace std;
#define in Read()
typedef long long ll;

int in{
    int i=0,f=1; char ch=0;
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') f=-1, ch=getchar();
    while('0'<=ch&&ch<='9') i=(i<<1)+(i<<3)+ch-48, ch=getchar();
    return i*f;
}

const int N=1e5+5;
const int INF=2147483647;
int n,q;
vector<int>G[N];
int faz[N],son[N],siz[N],top[N],dfn[N],cnt,dep[N],idx[N];
int tre[N<<2]; //tre[p] indicates the black node with the least depth, tre[p]==-1 means the node is white

void DFS1(int u,int fa){
    dep[u]=dep[fa]+1;
    faz[u]=fa;
    siz[u]=1;
    for(auto v:G[u]){
        if(v==fa) continue;
        DFS1(v,u);
        siz[u]+=siz[v];
        if(siz[son[u]]<siz[v]) son[u]=v;
    }
}

void DFS2(int u,int tp){
    top[u]=tp;
    dfn[u]=++cnt;
    idx[cnt]=u;
    if(!son[u]) return;
    DFS2(son[u],tp);
    for(auto v:G[u]){
        if(v==son[u]||v==faz[u]) continue;
        DFS2(v,v);
    }
}

#define lch p<<1
#define rch p<<1|1

void push_up(int p){
    tre[p]=min(tre[lch],tre[rch]);
}

void build(int p,int l,int r){
    if(l==r){
        tre[p]=INF;
        return;
    }
    int mid=l+r>>1;
    build(lch,l,mid);
    build(rch,mid+1,r);
    push_up(p);
}

void update(int p,int l,int r,int x){ //x is dfn[u]
    if(l==r){
        if(tre[p]==l) tre[p]=INF;
        else tre[p]=l;
        return;
    }
    int mid=l+r>>1;
    if(x<=mid) update(lch,l,mid,x);
    else update(rch,mid+1,r,x);
    push_up(p);
}

int query(int p,int l,int r,int L,int R){
    if(L<=l&&r<=R) return tre[p];
    int mid=l+r>>1,res=INF;
    if(L<=mid) res=min(res,query(lch,l,mid,L,R));
    if(mid<R) res=min(res,query(rch,mid+1,r,L,R));
    return res;
}

#undef lch
#undef rch

int Query(int u){
    int ans=INF;
    while(top[u]!=1){
        ans=min(ans,query(1,1,n,dfn[top[u]],dfn[u]));
        u=faz[top[u]];
    }
    ans=min(ans,query(1,1,n,1,dfn[u]));
    return ans;
}

int main(){

    // freopen("1.in","r",stdin);

    n=in,q=in;
    for(int i=1;i<n;++i){
        int u=in,v=in;
        G[u].push_back(v);
        G[v].push_back(u);
    }

    DFS1(1,0);
    DFS2(1,1);
    build(1,1,n);

    for(int i=1;i<=q;++i){
        int opt=in, u=in;
        if(opt==1){
            int res=Query(u);
            printf("%d\n",res==INF?-1:idx[res]);
        }
        if(opt==0) update(1,1,n,dfn[u]);
    }

    return 0;
    
}
posted @ 2022-11-20 16:16  antimo  阅读(26)  评论(0)    收藏  举报