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;
}

浙公网安备 33010602011771号