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
  • 相关阅读:
    面向对象三大特征之多态——Java笔记(七)
    面向对象三大特征之继承(extends)——Java笔记(六)
    this、访问修饰符——Java笔记(五)
    面向对象三大特征之封装与static——(Java学习笔记四)
    初识Java——(Java学习笔记一)
    HTTP/3 简介
    iis 500.19错误解决过程记录
    排序陷阱 List.Sort Linq.OrderBy
    锁的封装 读写锁、lock
    时间“Thu Aug 14 2014 14:28:06 GMT+0800”的转换
  • 原文地址:https://www.cnblogs.com/uuzlove/p/12292044.html
Copyright © 2011-2022 走看看