• Codeforces Round #629 (Div. 3) E


    E - Tree Queries

    题意:

    给一个n个点的树(以1为树根,每个点的距离是1),然后询问m次,t个点是否在树中的某条链上,如果没在链上,但离链距离是1的也是允许的

    思路:

    找到 t 个点最深的一个点,以这个点去查找其他点v的最近公共祖先d,最近公共祖先d的深度与v的深度大于1的就直接输出NO,如果全部符合就是YES

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define ull unsigned long long
     5 #define il inline
     6 #define it register int
     7 #define inf 0x3f3f3f3f
     8 #define lowbit(x) (x)&(-x)
     9 #define pii pair<int,int>
    10 #define mak(n,m) make_pair(n,m)
    11 #define mem(a,b) memset(a,b,sizeof(a))
    12 #define mod 998244353
    13 #define fi first
    14 #define se second
    15 #define sz(x) (int)(x).size()
    16 #define all(x) (x).begin(), (x).end()
    17 const int maxn=2e5+10;
    18 ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
    19 int n,t,m,tot,d[maxn];
    20 struct node{
    21     int next,dist,v;
    22 }a[maxn<<1];
    23 int fath[maxn][20], depth[maxn];
    24 int dist[maxn],head[maxn];
    25 void add(int u,int v,int dist0){
    26     a[tot].next=head[u];
    27     a[tot].dist=dist0;
    28     a[tot].v=v;
    29     head[u]=tot++;
    30 }
    31 void dfs(int u,int fa,int d) {
    32     fath[u][0]=fa; depth[u]=d;
    33     for(int i=1;i<20;i++) fath[u][i]=fath[fath[u][i-1]][i-1];
    34     for (int i=head[u];~i;i=a[i].next){
    35         int v=a[i].v;if(v==fa)continue;
    36         dist[v]=dist[u]+a[i].dist;
    37         dfs(v,u,d+1);
    38     }
    39 }
    40 void init(int n){
    41     for(int i=0;i<=n;i++)fath[i][0]=0,dist[i]=0,head[i]=-1,depth[i]=0;
    42     tot=0;
    43 }
    44 il int lca(int x,int y){
    45     if(depth[x]<depth[y])swap(x,y);
    46     int h=depth[x]-depth[y];
    47     for(it i=0;h>0;i++){
    48         if(h&1){
    49             x=fath[x][i];
    50         }
    51         h>>=1;
    52     }
    53     if(x==y)return x;
    54     for(it i=19;i>=0;i--){
    55         if(fath[x][i]!=fath[y][i]){
    56             x=fath[x][i];
    57             y=fath[y][i];
    58         }
    59     }
    60     return fath[x][0];
    61 }
    62 il int dis(int u,int v){
    63     int d=lca(u,v);//cout<<d<<" "<<depth[v]-depth[d]<<endl;
    64     if(depth[v]-depth[d]>1){return 1;}
    65     return 0;
    66 }
    67 int main(){
    68     scanf("%d%d",&n,&m);
    69     init(n);
    70     for(it i=1;i<n;i++){int w,v;scanf("%d%d",&w,&v);add(w,v,1);add(v,w,1);}
    71     dfs(1,0,1);
    72     while(m--){
    73         scanf("%d",&t);
    74         for(it i=0;i<t;i++){
    75             scanf("%d",&d[i]);
    76         }
    77         int shen=1,pos=1;
    78         for(it i=0;i<t;i++){
    79             if(depth[d[i]]>shen){
    80                 shen=depth[d[i]];pos=d[i];
    81             }
    82         }
    83         int f=1;
    84         for(it i=0;i<t;i++){
    85             if(dis(pos,d[i])){f=0;break;}
    86         }
    87         if(f){printf("YES
    ");}
    88         else{printf("NO
    ");}
    89     }
    90     return 0;
    91 }

    顺便说一下比赛过的A~D

    A题b-a%b,a%b==0

    B题找i*(i+1)/2最接近m的数字,然后m-i*(i+1)/2和i是b的位置(口胡,但当时思路是这样,我为了找i,用o(1)的方法写了50min+,我心态差点裂开了,最后还是用o(sqrtm)找了)

    C题第一个1出现之前,0分配0,0;2分配1,1。当1出现了分配1,0。第一个1出现之后0分配0,0;1分配0,1;2分配0,2 。

    D题只会出现1,2,3,只出现一个数是1,偶数就是2,以12循环n/2次,如果是奇数,如果有两个相同数连一块的,首位也要算进去,就是2,以1,2循环,直到出现相同数连一块,他们的颜色相同然后1,2的隔开,其余的就是3种颜色,以12循环n/2次,最后一位是3

  • 相关阅读:
    Serverless 解惑——函数计算如何安装字体
    构建安全可靠的微服务 | Nacos 在颜铺 SaaS 平台的应用实践
    OAM v1alpha2 新版:平衡标准与可扩展性
    人工智能与阅读能力的关系研究
    Java Web每天学之Servlet的原理解析
    ThreadLocal类的简单使用
    JavaScript之DOM创建节点
    css浮动(float)及清除浮动的几种实用方法
    Apache Sentry部署
    Spark机器学习解析下集
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/12584382.html
Copyright © 2020-2023  润新知