http://codeforces.com/contest/570/problem/D

给一棵有根树(50w个点)(指定根是1号节点),每个点上有一个小写字母,然后有最多50w个询问,每个询问给出x和f,表示询问以x为根的子树,在第f层的所有节点上的字符能否组成一个回文串

首先树形转线性,把每个点按照DFS序重新标号,然后开个vector记下第i层都有哪些节点,

对于这一层的节点,维护一个前缀和,即某个字母出现过多少次,

这样对于某个询问x,f,我们能知道x为根的子树在线性数组中的序号范围,

然后二分查找第f层位于这个范围的点,通过前缀和就很容易求出来某个字母出现过多少次

因为回文串中最多有一个字母出现奇数次,所以就可以判断是否是回文串。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<sstream>
#define eps 1e-9
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define MAXN 500005
#define MAXM 40005
#define INF 0x3fffffff
#define PB push_back
#define MP make_pair
#define X first
#define Y second
#define clr(x,y) memset(x,y,sizeof(x));
using namespace std;
typedef long long LL;
int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
bool flag; vector<int> G[MAXN],D[MAXN];
int op[MAXN],ed[MAXN],lin[MAXN],d[MAXN],mxdp;
int ti[MAXN][];
char s[MAXN];
int p[]; void dfs(int u,int f)
{
d[u]=f;
mxdp=max(mxdp,f);
lin[num]=u;//线性数组
op[u]=num;//子树的起始位置
D[f].PB(num); //D[f]表示f层都有哪些节点
num++;
for (int i=;i<G[u].size();i++)
{
int v=G[u][i];
dfs(v,f+);
}
ed[u]=num-;//子树的终止位置
} int main()
{
scanf("%d%d",&n,&m);
for (i=;i<=n;i++)
{
scanf("%d",&x);
G[x].PB(i);
}
scanf("%s",s+);
for (i=;i<=n;i++) D[i].PB();
num=;
dfs(,);
for (i=;i<=mxdp;i++)
{
for (j=;j<D[i].size();j++)
{
int u=D[i][j-];
int v=D[i][j];
for (k=;k<;k++) ti[v][k]=ti[u][k];//ti[u][k]表示节点u所在的那一层,从开始到节点u,各个字母出现的次数 ti[v][s[ lin[v] ]-'a']++;
}
} for (i=;i<=m;i++)
{
int u,f;
scanf("%d%d",&u,&f);
int l=op[u],r=ed[u];
int s=upper_bound(D[f].begin(),D[f].end(),l)-D[f].begin()-;
int e=upper_bound(D[f].begin(),D[f].end(),r)-D[f].begin()-;
if (s>=e)
{
printf("Yes\n");
}else
{
int cnt=;
e=D[f][e];
s=D[f][s];
for (k=;k<;k++)
if ((ti[e][k]-ti[s][k]) % ) cnt++;
if (cnt>) printf("No\n");
else printf("Yes\n");
}
}
return ;
}

Codeforces 570D - Tree Requests【树形转线性,前缀和】的更多相关文章

  1. Codeforces 570D - Tree Requests(树上启发式合并)

    570D - Tree Requests 题意 给出一棵树,每个节点上有字母,查询 u k,问以 u 为根节点的子树下,深度为 k 的所有子节点上的字母经过任意排列是否能构成回文串. 分析 一个数组 ...

  2. Codeforces 570D TREE REQUESTS dfs序+树状数组 异或

    http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...

  3. Codeforces 570D TREE REQUESTS dfs序+树状数组

    链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...

  4. CodeForces 570D - Tree Requests - [DFS序+二分]

    题目链接:https://codeforces.com/problemset/problem/570/D 题解: 这种题,基本上容易想到DFS序. 然后,我们如果再把所有节点分层存下来,那么显然可以根 ...

  5. codeforces 570D.Tree Requests

    [题目大意]: 给定一棵树,树的每个节点对应一个小写字母字符,有m个询问,每次询问以vi为根节点的子树中,深度为hi的所有节点对应的字符能否组成一个回文串: [题目分析]: 先画个图,可看出每次询问的 ...

  6. CF 570D. Tree Requests [dsu on tree]

    传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...

  7. CodeForces 466E Information Graph --树形转线性+并查集

    题意:有三种操作: 1.新增一条边从y连向x,此前x没有父节点 2.x接到一份文件,(文件标号逐次递增),然后将这份文件一路上溯,让所有上溯的节点都接到这份文件 3.查询某个节点x是否接到过文件F 解 ...

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

    D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  9. codeforces 570 D. Tree Requests 树状数组+dfs搜索序

    链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...

随机推荐

  1. LightOj_1030 Discovering Gold

    题目链接 题意: 在一个1 X N 的格子上, 每个格子都有一定的黄金, 你从第一个格子出发, 问到最后一个格子得到黄金的期望. 每次前进使用骰子投点来决定前进步数, 如果投出的点前进后会超过N, 那 ...

  2. PHP-mac下的配置及运行

    Here's another option, from the guys from liip, here. This is a PHP package that comes pre-built for ...

  3. data guard switchover切换异常

    data guard switchover切换异常 查看DG数据库备份库发现,switchover_status为SWITCHOVER LATENT SQL> select OPEN_MODE, ...

  4. 使用HttpServletRequestWrapper在filter修改request参数

    javax.servlet.ServletRequest中的 Map<String, String[]> parameterMap = request.getParameterMap(); ...

  5. Android listView scroll 恢复滚动位置

    相信大家尝试过许多方法恢复滚动位置,本人也找了许多方法,唯有这个方法好用,下面把代码贴出来 声明两个变量 private int mPosition; private int lvChildTop; ...

  6. Dynamic系列--Dynamic 与反序列化

    通常在调用其他站点的api时,如果返回的结果为 json数据,而我们又不想再重新定义实体类时,可以使用dynamic类型. 但是有以下需要注意的地方. 当内容为空时,反序列化结果为null 当内容格式 ...

  7. Spring - Sring MVC入门

    2.1.Spring Web MVC是什么 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职 ...

  8. Linux Shell编程(21)——复杂命令

    更高级的用户命令find-exec COMMAND \;在每一个find 匹配到的文件执行 COMMAND 命令. 命令序列以 ; 结束( ";" 是 转义符 以保证 shell ...

  9. 水题:HDU 5112 A Curious Matt

    Description There is a curious man called Matt. One day, Matt's best friend Ted is wandering on the ...

  10. 简单的javascript例子

    <html> <head> <title>hongmaju</title> <link rel="shortcut icon" ...