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
",ans);
126         }
127     }
128     
129     return 0;
130 }
View Code

;

原文地址:https://www.cnblogs.com/csushl/p/10196827.html