zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    [05] EL表达式
    [03-01] JSP自定义标签
    [04] JSP标准动作
    [03] JSP指令
    Fiddler抓包调试前端脚本代码
    《互联网协议入门》思维导图笔记
    Nodejs学习笔记(十)—与MongoDB的交互(mongodb/node-mongodb-native)、MongoDB入门
    Nodejs学习笔记(九)—与Redis的交互(mranney/node_redis)入门
    Nodejs学习笔记(八)—Node.js + Express 实现上传文件功能(felixge/node-formidable)
    Nodejs学习笔记(七)—Node.js + Express 构建网站简单示例
  • 原文地址:https://www.cnblogs.com/uuzlove/p/12292044.html
Copyright © 2011-2022 走看看