• codeforces 466E


    我们考虑离线,把第三种操作挂在第二种上,那么我们只需要查询对应时刻的森林中某个点是不是当前操作点的祖先即可

    因为只有加边操作,我们把森林的祖先后代关系变成判断他在离线的最终树上的祖先后代关系和判断两点是否连通

    并查集维护连通性,LCA查询祖先后代关系

    复杂度(O(m log n))

     1 #include<bits/stdc++.h>
     2 #define maxn 100005
     3 using namespace std;
     4 int n,m;
     5 struct Opt
     6 {
     7     int op,x,y;
     8     Opt(int OP=0,int X=0,int Y=0):op(OP),x(X),y(Y){}
     9 }opt[maxn];
    10 vector< pair<int,int> > qry[maxn];
    11 int Ans[maxn];
    12 int m1,m2;
    13 int fa[maxn];
    14 int find(int x){if(fa[x]==x)return x;else return fa[x]=find(fa[x]);}
    15 vector<int> g[maxn];
    16 bool isroot[maxn];
    17 int anc[maxn][20],d[maxn];
    18 void dfs(int u)
    19 {
    20     for(int v:g[u])
    21     {
    22         d[v]=d[u]+1;anc[v][0]=u;
    23         dfs(v);
    24     }
    25 }
    26 int LCA(int u,int v)
    27 {
    28     if(d[u]<=d[v])swap(u,v);
    29     for(int i=18;i>=0;--i)if(d[anc[u][i]]>=d[v])u=anc[u][i];
    30     if(u==v)return u;
    31     for(int i=18;i>=0;--i)if(anc[u][i]!=anc[v][i])u=anc[u][i],v=anc[v][i];
    32     return anc[u][0];
    33 }
    34 int main()
    35 {
    36     scanf("%d%d",&n,&m);
    37     for(int i=1;i<=n;++i)fa[i]=i,isroot[i]=1;
    38     for(int i=1;i<=m;++i)
    39     {
    40         int t,x,y;
    41         scanf("%d%d",&t,&x);
    42         if(t!=2)scanf("%d",&y);
    43         if(t==1)opt[++m1]=Opt(t,x,y),g[y].push_back(x),isroot[x]=0;
    44         if(t==2)opt[++m1]=Opt(t,x);
    45         if(t==3)qry[y].push_back(make_pair(x,++m2));
    46     }
    47     for(int i=1;i<=n;++i)if(isroot[i])g[0].push_back(i);
    48     dfs(0);
    49     for(int j=1;j<=18;++j)
    50         for(int i=1;i<=n;++i)anc[i][j]=anc[anc[i][j-1]][j-1];
    51     int id=0;
    52     for(int i=1;i<=m1;++i)
    53     {
    54         int t,x,y;
    55         t=opt[i].op,x=opt[i].x,y=opt[i].y;
    56         if(t==1)
    57         {
    58             if(find(x)!=find(y))fa[find(x)]=find(y);
    59         }
    60         if(t==2)
    61         {
    62             ++id;
    63             for(auto pa:qry[id])
    64             {
    65                 int u=x,v=pa.first;
    66                 if(LCA(u,v)==v&&find(u)==find(v))Ans[pa.second]=1;
    67                 else Ans[pa.second]=0;
    68             }
    69         }
    70     }
    71     for(int i=1;i<=m2;++i)if(Ans[i])puts("YES");else puts("NO");
    72 }
    View Code
  • 相关阅读:
    Navicat破解安装
    jrebel and xrebel
    JMTER连接数据库
    jmter参数化
    JMTER逻辑控制器
    JMter定时器和聚合报告
    Jmter文件上传
    npm安装教程
    adb调试工具
    Jmter前/后置处理器
  • 原文地址:https://www.cnblogs.com/uuzlove/p/12292044.html
Copyright © 2020-2023  润新知