zoukankan      html  css  js  c++  java
  • 解题:CF570D Tree Requests

    题面

    DSU on tree确实很厉害,然后这变成了一道裸题(逃

    还是稍微说一下流程吧,虽然我那个模板汇总里写过

    DSU on tree可以以$O(nlog n)$的复杂度解决树上子树统计问题,它这样工作:

    前置工作:对树进行轻重链剖分

    1.递归求解所有的轻儿子,在回溯时消去影响

    2.递归进入重儿子,在回溯时不消去影响

    3.暴力统计子树信息

    4.回答询问并回溯

    根据轻重链剖分的性质,复杂度$O(nlog n)$

     1 #include<cstdio>
     2 #include<vector>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=500005;
     7 vector<pair<int,int> > qry[N];
     8 int siz[N],dep[N],imp[N],sta[N],vis[N],outp[N];
     9 int p[N],noww[2*N],goal[2*N];
    10 int n,m,t1,t2,rd,cnt;
    11 char str[N];
    12 void Link(int f,int t)
    13 {
    14     noww[++cnt]=p[f];
    15     goal[cnt]=t,p[f]=cnt;
    16     noww[++cnt]=p[t];
    17     goal[cnt]=f,p[t]=cnt;
    18 }
    19 int Bitcount(int s)
    20 {
    21     int ret=0;
    22     while(s)
    23         ret++,s-=s&-s;
    24     return ret;
    25 }
    26 void DFS(int nde,int fth,int dth)
    27 {
    28     int tmp=0;
    29     siz[nde]=1,dep[nde]=dth;
    30     for(int i=p[nde];i;i=noww[i])
    31         if(goal[i]!=fth)
    32         {
    33             DFS(goal[i],nde,dth+1);
    34             siz[nde]+=siz[goal[i]];
    35             if(siz[goal[i]]>tmp)
    36                 tmp=siz[goal[i]],imp[nde]=goal[i];
    37         }
    38 }
    39 void Count(int nde,int fth)
    40 {
    41     sta[dep[nde]]^=1<<(str[nde]-'a');
    42     for(int i=p[nde];i;i=noww[i])
    43         if(goal[i]!=fth&&!vis[goal[i]])
    44             Count(goal[i],nde);
    45 }
    46 void Getans(int nde,int fth,int hvy)
    47 {
    48     for(int i=p[nde];i;i=noww[i])
    49         if(goal[i]!=fth&&goal[i]!=imp[nde])
    50             Getans(goal[i],nde,0);
    51     if(imp[nde])
    52         Getans(imp[nde],nde,1),vis[imp[nde]]=true;
    53     Count(nde,fth);
    54     vector<pair<int,int> >::iterator it;
    55     for(it=qry[nde].begin();it!=qry[nde].end();it++)
    56     {
    57         int dth=it->second;
    58         outp[it->first]=(Bitcount(sta[dth])<=1);
    59     }
    60     if(imp[nde]) vis[imp[nde]]=false;
    61     if(!hvy) Count(nde,fth);
    62 }
    63 int main()
    64 {
    65     scanf("%d%d",&n,&m);
    66     for(int i=1;i<n;i++)
    67         scanf("%d",&t1),Link(t1,i+1);
    68     scanf("%s",str+1);
    69     for(int i=1;i<=m;i++)
    70     {
    71         scanf("%d%d",&t1,&t2);
    72         qry[t1].push_back(make_pair(i,t2));
    73     }
    74     DFS(1,0,1),Getans(1,0,0);
    75     for(int i=1;i<=m;i++)
    76         outp[i]?puts("Yes"):puts("No");
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    JAVA代码中加了Try...Catch的执行顺序
    Java的注解机制——Spring自动装配的实现原理
    UWP蓝牙的例子
    MIT License
    Windows 运行时组件
    VS 的编译选项 build下的 platform target -- Any CPU和x86有什么影响?
    swfdump——从内存中提取swf的工具
    生成某一文件夹内文件清单(批量处理)
    统一用户认证和单点登录解决方案
    关键路径计算、总时差、自由时差
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10162633.html
Copyright © 2011-2022 走看看