• 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

    ;

  • 相关阅读:
    友盟统计,监听事件次数。
    webView 加载网页
    Springboot 启动时Bean初始化,启动异常-Assert.isTrue(condition,message) 报错
    Springboot使用@ConfigurationProperties注解 配置读不进去
    2018即将结束,给寒假李哥flag
    大精度求和,给任意两个数 m,n 甚至m,n->∞ 计算x+y
    第二章JavaScript 函数和对象
    第三章JavaScript 内置对象
    响应式网页设计
    新的页面布局方式
  • 原文地址:https://www.cnblogs.com/csushl/p/10196827.html
Copyright © 2020-2023  润新知