• 2022牛客多校Day2 A(LCA)


    这题主要学习两点,一个是LCA具有可加性,这个在做题的时候考虑到了;

    另一个是对于在一个具备可加性的点集中去除一个点再看剩下点的影响,可以考虑预处理出前缀和以及后缀和,然后枚举删掉的节点进行计算。rainy说这是非常常见的套路。

     1 #include "bits/stdc++.h"
     2 using namespace std;
     3 const int MAX=2e5+5;
     4 int n,m,w[MAX];
     5 int weia[MAX],weib[MAX];
     6 int lcal[MAX],lcar[MAX],lcbl[MAX],lcbr[MAX];
     7 int tot,head[MAX],adj[MAX<<1],nxt[MAX<<1];
     8 int fa[MAX][21],deep[MAX];
     9 inline int read(){
    10     int an=0,x=1;char c=getchar();
    11     while (c<'0' || c>'9') {if (c=='-') x=-1;c=getchar();}
    12     while (c>='0' && c<='9') {an=(an<<3)+(an<<1)+c-'0';c=getchar();}
    13     return an*x;
    14 }
    15 void addedge(int u,int v){
    16     tot++;adj[tot]=v,nxt[tot]=head[u],head[u]=tot;
    17 }
    18 void dfs(int x,int ff){
    19     int i,j;
    20     for (i=1;i<=20;i++){
    21         if (deep[x]<(1<<i)) break;
    22         fa[x][i]=fa[ fa[x][i-1] ][i-1];
    23     }
    24     for (i=head[x];i;i=nxt[i]){
    25         if (adj[i]==ff) continue;
    26         fa[adj[i]][0]=x;deep[adj[i]]=deep[x]+1;
    27         dfs(adj[i],x);
    28     }
    29 }
    30 int lca(int x,int y){
    31     if (deep[x]<deep[y]) swap(x,y);
    32     int i,j,dd=deep[x]-deep[y];
    33     for (i=20;i>=0;i--)
    34         if (dd&(1<<i))
    35             x=fa[x][i];
    36     for (i=20;i>=0;i--)
    37         if (fa[x][i]!=fa[y][i])
    38             x=fa[x][i],y=fa[y][i];
    39     return x==y?x:fa[x][0];
    40 }
    41 int main(){
    42     freopen ("a.in","r",stdin);
    43     freopen ("a.out","w",stdout);
    44     int i,j,u,v;
    45     scanf("%d%d",&n,&m);
    46     for (i=1;i<=m;i++) scanf("%d",w+i);
    47     for (i=1;i<=n;i++) scanf("%d",weia+i);
    48     for (i=1;i<n;i++){
    49         scanf("%d",&v);
    50         addedge(v,i+1);
    51         addedge(i+1,v);
    52     }
    53     for (i=1;i<=n;i++) scanf("%d",weib+i);
    54     for (i=1;i<n;i++){
    55         scanf("%d",&v);
    56         addedge(v+n,i+1+n);
    57         addedge(i+1+n,v+n);
    58     }
    59     dfs(1,0);
    60     dfs(n+1,0);
    61     lcal[1]=w[1];lcar[m]=w[m];
    62     lcbl[1]=w[1]+n;lcbr[m]=w[m]+n;
    63     for (i=2;i<=m;i++){
    64         lcal[i]=lca(lcal[i-1],w[i]);
    65         lcbl[i]=lca(lcbl[i-1],w[i]+n);
    66 //        cout<<w[i]<<' '<<lcal[i]<<' '<<lcbl[i]-n<<endl;
    67     }
    68 //    cout<<endl;
    69     for (i=m-1;i>=1;i--){
    70         lcar[i]=lca(lcar[i+1],w[i]);
    71         lcbr[i]=lca(lcbr[i+1],w[i]+n);
    72 //        cout<<w[i]<<' '<<lcar[i]<<' '<<lcbr[i]-n<<endl;
    73     }
    74     int ans=0;
    75     if (weia[lcar[2]]>weib[lcbr[2]-n]) ans++;
    76     if (weia[lcal[m-1]]>weib[lcbl[m-1]-n]) ans++;
    77     for (i=2;i<m;i++){
    78         int xx=lca(lcal[i-1],lcar[i+1]);
    79         int yy=lca(lcbl[i-1],lcbr[i+1]);
    80         if (weia[xx]>weib[yy-n])
    81             ans++;
    82     }
    83     printf("%d",ans);
    84     return 0;
    85 }
  • 相关阅读:
    牛人一个
    hdu 1106 排序
    中国历史上著名的年号
    十万个为什么 —— 名词解释(历史)
    十万个为什么 —— 名词解释(历史)
    数学可视化
    数学可视化
    高观点下的初等数学
    高观点下的初等数学
    同一性(identical)
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/16523267.html
Copyright © 2020-2023  润新知