1. 程式人生 > >【NOIP2018模擬賽2018.10.3】到不了

【NOIP2018模擬賽2018.10.3】到不了

題目

在這裡插入圖片描述
在這裡插入圖片描述


題解

–大佬都用lct,像我這種弱雞就只有用一種神奇的做法了
首先離線
直接把最後的森林處理出來(並查集)
再跟著修改順序,在這些樹上跳lca
但是這不一定是最後的答案(因為樹不一定就是最後的樣子了)
所以我們還要用當前的真實根來判斷一下:
如果真實根和這兩個點的lca的深度比當前答案深
那就要更新答案
自己畫圖看看唄


程式碼

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm> using namespace std; const int MAXN=1e5+5; int n,m,q,a; int head[MAXN],to[2*MAXN],next[2*MAXN],cnt; int r[MAXN]; int c[MAXN][3]; int fa[MAXN][20],d[MAXN],f[MAXN],f1[MAXN]; void add(int u,int v){ cnt++; next[cnt]=head[u]; to[cnt]=v; head[u]=cnt; } void dfs(int x,int F)
{ f[x]=F; for(int i=head[x];i;i=next[i]){ int y=to[i]; if(y==fa[x][0]) continue; d[y]=d[x]+1; fa[y][0]=x; dfs(y,F); } } int get(int x){ if(x==f[x]) return x; return f[x]=get(f[x]); } int lca(int x,int y){ if(d[x]<d[y]) swap(x,y); for(int i=18;i>=0;i--) if(d[fa[x][i]]>=
d[y]) x=fa[x][i]; if(x==y) return x; for(int i=18;i>=0;i--) if(fa[x][i]!=fa[y][i]){ x=fa[x][i]; y=fa[y][i]; } return fa[x][0]; } int main(){ // freopen("data.in","r",stdin); // freopen("data.out","w",stdout); cin>>n>>m; for(int i=1;i<=m;i++) scanf("%d",&r[i]); cin>>a; for(int i=1;i<=n-m;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } for(int i=1;i<=m;i++){ d[r[i]]=1; dfs(r[i],r[i]); } for(int i=1;i<=n;i++) f1[i]=f[i]; cin>>q; for(int i=1;i<=q;i++){ int op,u,v; scanf("%d%d%d",&c[i][0],&c[i][1],&c[i][2]); op=c[i][0]; u=c[i][1]; v=c[i][2]; if(op==1){ int fu=get(u),fv=get(v); if(fu==fv) continue; add(u,v); add(v,u); f[fv]=fu; } } for(int i=1;i<=m;i++) if(get(r[i])==r[i]) dfs(r[i],r[i]); for(int j=1;j<=18;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; for(int i=1;i<=n;i++) f[i]=f1[i]; for(int i=1;i<=q;i++){ int op,u,v; op=c[i][0]; u=c[i][1]; v=c[i][2]; if(op==1){ int fu=get(u),fv=get(v); if(fu==fv) continue; f[fv]=fu; } else{ int fu=get(u),fv=get(v); if(fu!=fv){ printf("orzorz\n"); continue; } int dad=lca(u,v); int r=lca(u,fu); if(d[r]>d[dad]) dad=r; r=lca(v,fu); if(d[r]>d[dad]) dad=r; printf("%d\n",dad); } } return 0; }