zoukankan      html  css  js  c++  java
  • cf983E NN Country (倍增+dfs序+树状数组)

    首先可以求出从某点做$2^k$次车能到的最浅的点,这个只要dfs一下,把它的孩子能到的最浅的点更新过来就可以

    然后倍增地往上跳,不能跳到lca的上面,记录坐车的次数ans

    此时有三种情况(设最远能跳到x,y):

      1.再跳也跳不到lca的上面,就是-1

      2.路径(x,y)被某趟车覆盖,答案是ans+1

      3.并没有被覆盖,答案是ans+2

    那么怎么看有没有覆盖呢

    首先,如果这两个点是直上直下的(有一个是lca),只要看下面那个点能不能跳到上面去就行

    对于剩下的(x,y),只要有车的两端点分别在x和y的子树中就可以

    所以做一遍dfs,进某个点x的时候记下来y的子树中车端点的个数,然后把从x发的车的终点++,出来的时候再次统计那个个数,如果不相同,就说明(x,y)这条路径被覆盖了。这个在dfs序上用一个树状数组就可以

    不要把N写成M然后WA一页,很难看。

      1 #include<bits/stdc++.h>
      2 #define pa pair<int,int>
      3 #define CLR(a,x) memset(a,x,sizeof(a))
      4 using namespace std;
      5 typedef long long ll;
      6 const int maxn=2e5+10;
      7 
      8 inline ll rd(){
      9     ll x=0;char c=getchar();int neg=1;
     10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     12     return x*neg;
     13 }
     14 
     15 int eg[maxn][2],egh[maxn],ect;
     16 int N,M,Q,dep[maxn],fa[maxn][22],nxt[maxn][22];
     17 int dfn[maxn][2],tot,ans[maxn];
     18 int pt[maxn*2][2],pth[maxn],tr[maxn];
     19 int lq[maxn*2][2],lqh[maxn],tmp[maxn*2];
     20 bool covered[maxn];
     21 
     22 inline void adeg(int a,int b){
     23     eg[++ect][0]=b,eg[ect][1]=egh[a],egh[a]=ect;
     24 }
     25 
     26 void dfs(int x){
     27     dfn[x][0]=++tot;
     28     for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++)
     29         fa[x][i+1]=fa[fa[x][i]][i];
     30     for(int i=egh[x];i;i=eg[i][1]){
     31         int b=eg[i][0];
     32         dep[b]=dep[x]+1;
     33         dfs(b);
     34     }dfn[x][1]=tot;
     35 }
     36 
     37 int getlca(int x,int y){
     38     if(dep[x]<dep[y]) swap(x,y);
     39     for(int i=19;i>=0&&dep[x]!=dep[y];i--){
     40         if(fa[x][i]&&dep[fa[x][i]]>=dep[y])
     41             x=fa[x][i];
     42     }
     43     if(x==y) return x;
     44     for(int i=19;i>=0;i--){
     45         if(fa[x][i]!=fa[y][i])
     46             x=fa[x][i],y=fa[y][i];
     47     }
     48     return fa[x][0];
     49 }
     50 
     51 void dfs2(int x){
     52     for(int i=egh[x];i;i=eg[i][1]){
     53         int b=eg[i][0];
     54         dfs2(b);
     55         if(nxt[b][0]&&(dep[nxt[b][0]]<dep[nxt[x][0]]||!nxt[x][0]))
     56             nxt[x][0]=nxt[b][0];
     57     }
     58     if(dep[nxt[x][0]]>=dep[x]) nxt[x][0]=0;
     59 }
     60 
     61 inline int lowbit(int x){return x&(-x);}
     62 inline void add(int x,int y){
     63     for(;x<=N;x+=lowbit(x)) tr[x]+=y;
     64 }
     65 inline int query(int x){
     66     int re=0;for(;x;x-=lowbit(x)) re+=tr[x];return re;
     67 }
     68 
     69 void dfs3(int x){
     70     for(int i=lqh[x];i;i=lq[i][1]){
     71         int b=lq[i][0];
     72         tmp[i]=query(dfn[b][1])-query(dfn[b][0]-1);
     73     }
     74     for(int i=pth[x];i;i=pt[i][1]){
     75         int b=pt[i][0];
     76         add(dfn[b][0],1);
     77     }
     78     for(int i=egh[x];i;i=eg[i][1]){
     79         int b=eg[i][0];
     80         dfs3(b);
     81     }
     82     for(int i=lqh[x];i;i=lq[i][1]){
     83         int b=lq[i][0];
     84         if(tmp[i]!=query(dfn[b][1])-query(dfn[b][0]-1))
     85             covered[i>>1]=1;
     86     }
     87 }
     88 
     89 int main(){
     90     // freopen("983E.in","r",stdin);
     91     int i,j,k;
     92     N=rd();
     93     for(i=2;i<=N;i++){
     94         fa[i][0]=rd();
     95         adeg(fa[i][0],i);
     96     }
     97     dep[1]=1;dfs(1);
     98     M=rd();
     99     for(i=1;i<=M;i++){
    100         int a=rd(),b=rd();
    101         pt[i<<1][0]=a,pt[i<<1][1]=pth[b],pth[b]=i<<1;
    102         pt[i<<1|1][0]=b,pt[i<<1|1][1]=pth[a],pth[a]=i<<1|1;
    103         int x=getlca(a,b);
    104         if(dep[x]<dep[nxt[a][0]]||!nxt[a][0]) nxt[a][0]=x;
    105         if(dep[x]<dep[nxt[b][0]]||!nxt[b][0]) nxt[b][0]=x;
    106     }
    107     dfs2(1);
    108     for(i=0;i<19;i++){
    109         for(j=1;j<=N;j++){
    110             // if(!nxt[j][i]||!nxt[nxt[j][i]][i]) continue;
    111             nxt[j][i+1]=nxt[nxt[j][i]][i];
    112         }
    113     }
    114     Q=rd();
    115     for(i=1;i<=Q;i++){
    116         int a=rd(),b=rd(),lca=getlca(a,b);
    117         for(j=19;j>=0;j--){
    118             if(nxt[a][j]&&dep[nxt[a][j]]>dep[lca])
    119                 ans[i]+=1<<j,a=nxt[a][j];
    120         }
    121         for(j=19;j>=0;j--){
    122             if(nxt[b][j]&&dep[nxt[b][j]]>dep[lca])
    123                 ans[i]+=1<<j,b=nxt[b][j];
    124         }
    125         if((a==lca&&nxt[b][0]&&dep[nxt[b][0]]<=dep[lca])||(b==lca&&nxt[a][0]&&dep[nxt[a][0]]<=dep[lca]))
    126             ans[i]+=1;
    127         else if(nxt[a][0]&&nxt[b][0]&&dep[nxt[a][0]]<=dep[lca]&&dep[nxt[b][0]]<=dep[lca]){
    128             ans[i]+=2;
    129             lq[i<<1][0]=a,lq[i<<1][1]=lqh[b],lqh[b]=i<<1;
    130             lq[i<<1|1][0]=b,lq[i<<1|1][1]=lqh[a],lqh[a]=i<<1|1;
    131         }else{
    132             ans[i]=-1;
    133         }
    134     }
    135     dfs3(1);
    136     for(i=1;i<=Q;i++)
    137         printf("%d
    ",ans[i]-covered[i]);
    138     return 0;
    139 }
  • 相关阅读:
    elastic-job-console
    CentOS7_安装mysql5.7
    CentOS7_开放指定端口
    CentOS7_防火墙
    Docker-CentOS7-安装
    MySQL_写锁_lock tables tableName write
    cesium 动态流动纹理
    cesium加载二维贴地的地名(本地地名数据)
    python3.6安装open AI gym环境(windows)
    python PIL打开较大的tif影像时出错-OSError: cannot identify image file Image.open
  • 原文地址:https://www.cnblogs.com/Ressed/p/9811477.html
Copyright © 2011-2022 走看看