标签:void ESS case include 修改 cst struct span ace
给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白
有两种操作:
0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑)
1 v : 询问1到v的路径上的第一个黑点,若无,输出-1
输入格式:
第一行 N,Q,表示N个点和Q个操作
第二行到第N行N-1条无向边
再之后Q行,每行一个操作"0 i" 或者"1 v" (1 ≤ i, v ≤ N).
输出格式:
对每个1 v操作输出结果
输入输出样例:
9 8 1 2 1 3 2 4 2 9 5 9 7 9 8 9 6 8 1 3 0 8 1 6 1 7 0 2 1 9 0 2 1 9
输出:
-1 8 -1 2 -1
解:
题意要求我们单点修改颜色,查询距离。
这题当然不止LCT一种做法,也可以树剖。最近学了下LCT就练了一下QwQ.
我们先用一遍dfs求深度。求出深度后,LCT中维护除正常信息之外,维护点子树中黑点深度最浅的id编号以及点的col。
pushup:
inline void pushup(int x){ if(tr[x].col)tr[x].id=x; else tr[x].id=0; if(dep[tr[tr[x].ch[0]].id]<dep[tr[x].id])tr[x].id=tr[tr[x].ch[0]].id; if(dep[tr[rc].id]<dep[tr[x].id])tr[x].id=tr[rc].id; }
这个就不说了吧。
由于要dfs求深度,用前向星存边(树剖基本操作qwq),dfs即可。
(学树剖的话一定敲一下旅游那道题,基础操作比较全。)
记住,先dfs再Link!
每次单点修改,makeroot之后col^=1。
查询把v和1(伪根)split一下输出id即可。
代码:
#include<cstdio> #define MAXN 500000 #include<iostream> using namespace std; #define lc tr[x].ch[0] #define rc tr[x].ch[1] struct node{ int ch[2],fa,rev,id,col; }tr[500000]; int n,m,dep[MAXN],head[MAXN]; int tot,a[MAXN],b[MAXN],opt,f; struct EDGE{ int next,to; }e[MAXN]; inline bool root(int x){ int g=tr[x].fa; return !(tr[g].ch[1]==x||tr[g].ch[0]==x); } inline void pushup(int x){ if(tr[x].col)tr[x].id=x; else tr[x].id=0; if(dep[tr[tr[x].ch[0]].id]<dep[tr[x].id])tr[x].id=tr[tr[x].ch[0]].id; if(dep[tr[rc].id]<dep[tr[x].id])tr[x].id=tr[rc].id; }inline void pushr(int x){ if(!x)return; swap(tr[x].ch[0],tr[x].ch[1]); tr[x].rev^=1; }inline void pushdown(int x){ if(tr[x].rev){ pushr(tr[x].ch[0]); pushr(tr[x].ch[1]); tr[x].rev=0; } }inline void push(int x){ if(!root(x))push(tr[x].fa); pushdown(x); }inline void rotate(int x){ int y=tr[x].fa,z=tr[y].fa,k=tr[y].ch[1]==x; if(!root(y))tr[z].ch[tr[z].ch[1]==y]=x; tr[x].fa=z;tr[y].ch[k]=tr[x].ch[k^1]; if(tr[x].ch[k^1])tr[tr[x].ch[k^1]].fa=y; tr[y].fa=x;tr[x].ch[k^1]=y; pushup(y);pushup(x); }inline void splay(int x){ int y,z; push(x); while(!root(x)){ y=tr[x].fa,z=tr[y].fa; if(!root(y))(tr[z].ch[0]==y)^(tr[y].ch[0]==x)?rotate(x):rotate(y); rotate(x); }pushup(x); }inline void access(int x){for(int y=0;x;y=x,x=tr[x].fa){splay(x);tr[x].ch[1]=y;pushup(x);}} inline void makeroot(int x){ access(x);splay(x);pushr(x); }inline void split(int x,int y){ makeroot(x);access(y);splay(y); }inline void link(int x,int y){ makeroot(x);tr[x].fa=y; }inline void add(int x,int y){ e[++tot].to=y; e[tot].next=head[x]; head[x]=tot; }inline void dfs(int u,int fa) { dep[u]=dep[fa]+1; for(register int i=head[u] ; i ; i=e[i].next) if(e[i].to!=fa) dfs(e[i].to,u); } int main(){ // link(1,2);link(1,3); scanf("%d%d",&n,&m); for(int i=1;i<n;++i){ scanf("%d%d",&a[i],&b[i]); add(a[i],b[i]);add(b[i],a[i]); }dep[0]=0; dfs(1,0); //printf("Case:1#\n"); dep[0]=2147483647; // printf("Case:3#\n"); for(int i=1;i<n;++i)/*printf("Step%d %d %d\n",i,a[i],b[i]),*/link(a[i],b[i])/*,printf("Case:4#%d\n",i)*/; // printf("Case:2#\n"); for(int i=1;i<=m;++i){ scanf("%d%d",&opt,&f); if(!opt)makeroot(f),tr[f].col^=1; else{ split(1,f); printf("%d\n",tr[f].id==0?-1:tr[f].id); } }return 0; }
地理中考:
... int main(){ int grades=0,rp=0; while(727){ rp++;grades++; } return 0; }
标签:void ESS case include 修改 cst struct span ace
原文地址:https://www.cnblogs.com/h-lka/p/10993038.html