Codeforces Round #316 (Div. 2) D计算在一棵子树内某高度的节点

题:https://codeforces.com/contest/570/problem/D

题意:给定一个以11为根的n个节点的树,每个点上有一个字母(a~z),每个点的深度定义为该节点到11号节点路径上的点数.每次询问a,ba,b查询以aa为根的子树内深度为bb的节点上的字母重新排列之后是否能构成回文串。
分析:很明显是个树上启发式合并。显然,只要深度为bb结点的所有颜色中,至多有一种的数量为奇数就可以构成回文串了。

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
typedef long long ll;
const int M=5e5+5;
int sz[M],son[M],deep[M],w[M],countt[M][30],ans[M],vis[M];
char s[M];
vector<int>g[M];
vector<pair<int,int> >Q[M];

void dfs1(int u,int fa){
    sz[u]=1;
    deep[u]=deep[fa]+1;
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        dfs1(v,u);
        sz[u]+=sz[v];
        if(sz[v]>sz[son[u]])
            son[u]=v;
    }
}
void update(int u,int k){
    countt[deep[u]][w[u]]+=k;
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(!vis[v])
        update(v,k);
    }
}
void dfs2(int u,int sign){
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v!=son[u])
            dfs2(v,0);
    }
    if(son[u])
        dfs2(son[u],1),vis[son[u]]=1;
    update(u,1);
    for(int i=0;i<Q[u].size();i++){
        int num=0;
        int id=Q[u][i].first;
        int d=Q[u][i].second;
        for(int j=0;j<26;j++){
            if(countt[d][j]&1)
                num++;
        }
        if(num>1)
            ans[id]=0;
        else
            ans[id]=1;
    }
    vis[son[u]]=0;
    if(!sign)
        update(u,-1);
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int u,i=2;i<=n;i++){
        scanf("%d",&u);
        g[u].pb(i);
    }
    scanf("%s",s);
    for(int i=0;i<n;i++)
        w[i+1]=s[i]-‘a‘;
    for(int u,v,i=1;i<=m;i++){
        scanf("%d%d",&u,&v);
        Q[u].pb(make_pair(i,v));
    }
    dfs1(1,0);
    dfs2(1,0);
    for(int i=1;i<=m;i++)
        if(ans[i])
            printf("Yes\n");
        else
            printf("No\n");
    return 0;
}

原文地址:https://www.cnblogs.com/starve/p/12233989.html

时间: 2024-09-29 23:03:09

Codeforces Round #316 (Div. 2) D计算在一棵子树内某高度的节点的相关文章

Codeforces Round #406 (Div. 2) E. Till I Collapse(主席树)

题目链接:Codeforces Round #406 (Div. 2) E. Till I Collapse 题意: 给你n个数,对于每一个k(1<=k<=n),划分区间,每个区间只能有k个不同的数字, 问最小的划分区间的个数. 题解: 用主席树倒着将数插入,对于每个区间询问第k个不同数的位置就行了. #include<bits/stdc++.h> #define F(i,a,b) for(int i=a;i<=b;i++) #define ___ freopen("

Codeforces Round #316 (Div. 2)E. Pig and Palindromes DP

E. Pig and Palindromes Peppa the Pig was walking and walked into the forest. What a strange coincidence! The forest has the shape of a rectangle, consisting of n rows and m columns. We enumerate the rows of the rectangle from top to bottom with numbe

Codeforces Round #316 (Div. 2) (ABC题)

A - Elections 题意: 每一场城市选举的结果,第一关键字是票数(降序),第二关键字是序号(升序),第一位获得胜利: 最后的选举结果,第一关键字是获胜城市数(降序),第二关键字是序号(升序),第一位获得胜利: 求最后选举获胜者. 思路: 直接模拟即可. 代码: /* * @author FreeWifi_novicer * language : C++/C */ #include<cstdio> #include<iostream> #include<cstring

Codeforces Round #316 (Div. 2) B. Simple Game

思路:把n分成[1,n/2],[n/2+1,n],假设m在左区间.a=m+1,假设m在右区间,a=m-1.可是我居然忘了处理1,1这个特殊数据.被人hack了. 总结:下次一定要注意了,提交前一定要看下边界数据,不要急着交. 题目链接:http://codeforces.com/problemset/problem/570/B <pre name="code" class="cpp">#include<bits/stdc++.h> using

Codeforces Round #316 (Div. 2) C. Replacement

题意:给定一个字符串,里面有各种小写字母和' . ' ,无论是什么字母,都是一样的,假设遇到' . . ' ,就要合并成一个' .',有m个询问,每次都在字符串某个位置上将原来的字符改成题目给的字符,问每次须要多少次合并次数.才使字符串没有' .. ' 思路:最原始的想法,就是对于每一次询问,都遍历整个字符串.这样时间复杂度o(n*m),就高达10^10方,非常明显会tle. 换下思路,事实上每次询问所改变的字符都会保留到下一次.也就是下一次的次数就会受到上一次的影响,那么我仅仅要就算出第一次的

Codeforces Round #316 (Div. 2) 简单题解

简单小结:A题先找出每个城市中得票最高的然后再在以上求出的那帮人中出一个得票(一个城市只算一票)中最高的 1 /*********************************** 2 * * 3 * Auther Rhapsody * 4 * E-mail [email protected] * 5 * * 6 ***********************************/ 7 #include <set> 8 #include <map> 9 #include &l

Codeforces Round #316 (Div. 2) A

Description The country of Byalechinsk is running elections involving n candidates. The country consists of m cities. We know how many people in each city voted for each candidate. The electoral system in the country is pretty unusual. At the first s

Codeforces Round #316 (Div. 2) D Tree Requests

官方题解是离线询问,dfs树形转线性,然后二分找区间. 还有一种比较好的做法是直接dfs,将当前访问这个结点u相关的询问之前的状态存起来,然后访问完以后利用异或开关性,得到这颗子树上的答案. 代码是学习别人的http://blog.csdn.net/squee_spoon/article/details/47666667 当时做的时候想得是树形转线性,觉得dfs会暴栈,想用bfs,之前又没写过,于是愣了一个钟头. #include<bits/stdc++.h> using namespace

2017-4-30-Train:Codeforces Round #316 (Div. 2)

A. Elections(模拟) The country of Byalechinsk is running elections involving n candidates. The country consists of m cities. We know how many people in each city voted for each candidate. The electoral system in the country is pretty unusual. At the fi