CF 526F Max Mex(倍增求LCA+线段树路径合并)
Max Mex
题目地址:https://codeforces.com/contest/1084/problem/F
然后合并时注意分情况讨论:
参考代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb push_back 4 #define mkp make_pair 5 #define fi first 6 #define se second 7 typedef long long ll; 8 typedef pair<int,int> PII; 9 const int INF=0x3f3f3f3f; 10 inline int read() 11 { 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} 14 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 const int maxn=2e5+10; 18 int n,q,typ,x,y,cnt,ans; 19 int a[maxn],in[maxn],out[maxn]; 20 int dep[maxn],fc[21],fa[21][maxn]; 21 vector<int> G[maxn]; 22 PII res; 23 24 inline void dfs(int u) 25 { 26 in[u]=++cnt; 27 for(int i=1;fc[i]<=dep[u];++i) fa[i][u]=fa[i-1][fa[i-1][u]]; 28 for(int i=0,len=G[u].size();i<len;++i) 29 { 30 dep[G[u][i]]=dep[u]+1;fa[0][G[u][i]]=u; 31 dfs(G[u][i]); 32 } 33 out[u]=++cnt; 34 } 35 36 inline int LCA(int x,int y) 37 { 38 if(dep[x]<dep[y]) swap(x,y); 39 for(int i=0,t=dep[x]-dep[y];t;++i) 40 if(t&fc[i]) x=fa[i][x],t^=fc[i]; 41 for(int i=20;~i;--i) if(fa[i][x]^fa[i][y]) 42 x=fa[i][x],y=fa[i][y]; 43 return x==y? x:fa[0][x]; 44 } 45 46 namespace Segment 47 { 48 #define ls (rt<<1) 49 #define rs (rt<<1|1) 50 PII T[maxn<<2]; 51 52 bool anc(int x,int y){return in[x]<=in[y]&&out[x]>=out[y];} 53 54 PII check(PII x,int y) 55 { 56 if(!x.fi || !y) return mkp(0,0); 57 if(anc(x.fi,x.se)) swap(x.fi,x.se); 58 if(anc(x.se,x.fi)) 59 { 60 if(anc(x.fi,y)) return mkp(y,x.se); 61 if(anc(x.se,y)) 62 { 63 if(anc(y,x.fi)) return x; 64 if(LCA(x.fi,y)==x.se) return mkp(x.fi,y); 65 return mkp(0,0); 66 } 67 return mkp(y,x.fi); 68 } 69 70 if(anc(x.fi,y)) return mkp(y,x.se); 71 if(anc(x.se,y)) return mkp(x.fi,y); 72 if(!anc(LCA(x.fi,x.se),y)) return mkp(0,0); 73 if(!anc(y,x.fi) && !anc(y,x.se)) return mkp(0,0); 74 return x; 75 } 76 77 PII merge(PII x,PII y) 78 { 79 if(x.fi==-1) return y; 80 x=check(x,y.fi);x=check(x,y.se); 81 return x; 82 } 83 84 void update(int rt,int l,int r,int pos,int x) 85 { 86 if(l==r){T[rt]=mkp(x,x);return ;} 87 int mid=l+r>>1; 88 if(pos<=mid) update(ls,l,mid,pos,x); 89 else update(rs,mid+1,r,pos,x); 90 T[rt]=merge(T[ls],T[rs]); 91 } 92 93 bool query(int rt,int l,int r) 94 { 95 PII tmp=merge(res,T[rt]); 96 if(tmp.fi){res=tmp;ans=r;return true;} 97 if(l==r) return false;// 98 int mid=l+r>>1; 99 if(query(ls,l,mid)) query(rs,mid+1,r); 100 return false; 101 } 102 } 103 using namespace Segment; 104 105 int main() 106 { 107 n=read(); fc[0]=1; 108 for(int i=1;i<=n;++i) a[i]=read()+1; 109 for(int i=2;i<=n;++i) G[read()].pb(i); 110 for(int i=1;i<=20;++i) fc[i]=fc[i-1]<<1; 111 dfs(1); 112 for(int i=1;i<=n;++i) update(1,1,n,a[i],i); 113 q=read(); 114 while(q--) 115 { 116 typ=read(); 117 if(typ==1) 118 { 119 x=read();y=read();swap(a[x],a[y]); 120 update(1,1,n,a[x],x);update(1,1,n,a[y],y); 121 } 122 else 123 { 124 res=mkp(-1,0);ans=1;query(1,1,n); 125 printf("%d\n",ans); 126 } 127 } 128 129 return 0; 130 }
;