D
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Roman planted a tree consisting of n vertices. Each vertex contains a lowercase English letter. Vertex 1 is the root of the tree, each of then - 1 remaining vertices has a parent in the tree. Vertex is connected with its parent by an edge. The parent of vertex i is vertex pi, the parent index is always less than the index of the vertex (i.e., pi < i).

The depth of the vertex is the number of nodes on the path from the root to v along the edges. In particular, the depth of the root is equal to 1.

We say that vertex u is in the subtree of vertex v, if we can get from u to v, moving from the vertex to the parent. In particular, vertex v is in its subtree.

Roma gives you m queries, the i-th of which consists of two numbers vihi. Let's consider the vertices in the subtree vi located at depthhi. Determine whether you can use the letters written at these vertices to make a string that is a palindrome. The letters that are written in the vertexes, can be rearranged in any order to make a palindrome, but all letters should be used.

Input

The first line contains two integers nm (1 ≤ n, m ≤ 500 000) — the number of nodes in the tree and queries, respectively.

The following line contains n - 1 integers p2, p3, ..., pn — the parents of vertices from the second to the n-th (1 ≤ pi < i).

The next line contains n lowercase English letters, the i-th of these letters is written on vertex i.

Next m lines describe the queries, the i-th line contains two numbers vihi (1 ≤ vi, hi ≤ n) — the vertex and the depth that appear in the i-th query.

Output

Print m lines. In the i-th line print "Yes" (without the quotes), if in the i-th query you can make a palindrome from the letters written on the vertices, otherwise print "No" (without the quotes).

题解:把相同深度的点存入一个数组中,每个点都是当前这个点的在树中查找的时间  在询问的时候就按照深度在相应的 数组中找出 时间区间在某个区间内的点就ok了

#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <cstdio>
using namespace std;
#define mk make_pair
#define pub push_back
const int maxn=;
int num[maxn],depth[maxn],childmaxdepth[maxn];
int in[maxn],out[maxn],tim;
vector<int>G[maxn];
char str[maxn];
vector< pair<int,int> >D[maxn];
void dfs(int cur,int de)
{
int siz=G[cur].size();
in[cur]=++tim;
depth[cur]=childmaxdepth[cur]=de;
if(D[de].size()<){
D[de].pub(mk(,));
}
int d=str[cur-]-'a';
D[de].pub(mk(in[cur],D[de].back().second^(<<d)));
for(int i=; i<siz; i++)
{
int to=G[cur][i];
dfs(to,de+);
childmaxdepth[cur]=max(childmaxdepth[cur],childmaxdepth[to]); }
out[cur]=++tim;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==)
{
tim=;
for(int i=; i <= n; i++)
{
int d;
scanf("%d",&d);
G[d].push_back(i);
}
scanf("%s",str);
dfs(,);
for(int i=; i<m; i++)
{
int val,c;
scanf("%d%d",&val,&c);
if(childmaxdepth[val]<c||c<=depth[val])
{
puts("Yes");continue;
}
int L=lower_bound(D[c].begin(),D[c].end(),
mk(in[val],-))-D[c].begin();
int R=lower_bound(D[c].begin(),D[c].end(),
mk(out[val],-))-D[c].begin();
int t=D[c][L-].second^D[c][R-].second;
int ok=t-(t&(-t));
if(ok)puts("No");
else puts("Yes");
} }
return ;
}

E

给了一个矩阵 每个格子中有一个字符 然后要求从11 走到 nm 点 是一个回文串 只能从 向右或者向下走

我们枚举步数,然后 dp[x1][x2]可以得到 现在的点 (x1,y1), (x2,y2),然后我们再次使用利用滚动数组可以得到想要的  从之前的那些点得到

//向左向右 add(dp[cur][x1][x2],dp[cur^1][x1][x2]);

//向左向上 add(dp[cur][x1][x2],dp[cur^1][x1][x2+1]);

//向下向右 add(dp[cur][x1][x2],dp[cur^1][x1-1][x2]);

//向下向上 add(dp[cur][x1][x2],dp[cur^1][x1-1][x2+1]);

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn=;
long long dp[][maxn][maxn];
char str[maxn][maxn];
const int mod=;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=; i<n; i++)
scanf("%s",str[i]);
if(n+m<=){
printf("%d\n",str[][]==str[n-][m-]); return ;
}
if(str[][]!=str[n-][m-]){
printf("%d\n",);return ;
}
for(int i=; i<n; i++)
for(int j=; j<m; j++)dp[][i][j]=;
dp[][][n-]=;
int cur=;
for(int step=; step<(n+m)/;step++)
{
cur^=;
memset(dp[cur],,sizeof(dp[cur]));
for(int i=; i < n&&i<=step; i++)
for(int j=n-; j>=&&j>=i&&n--j<=step;j--)
{
if( ( step - i )> ( m - - ( step-( n - - j ) ) ) )continue;
int x1=i,x2=j,y1=step-i,y2=m--(step-(n--j));
if(str[x1][y1]!=str[x2][y2])continue;
dp[cur][x1][x2]=dp[cur^][x1][x2];
dp[cur][x1][x2]=( dp[cur][x1][x2] + dp[cur^][x1][x2+] )%mod;
if(x1>)
{
dp[cur][x1][x2]=( dp[cur][x1][x2] + dp[cur^][x1-][x2] )%mod;
dp[cur][x1][x2]=( dp[cur][x1][x2] + dp[cur^][x1-][x2+] )%mod;
} }
}
long long ans=;
for(int i=; i<n; i++)
ans=(ans+dp[cur][i][i])%mod;
if( (n+m)%){ for(int i=; i<n-; i++)
ans=(ans+dp[cur][i][i+])%mod;
}
printf("%I64d\n",ans);
return ;
}

D Tree Requests dfs+二分 D Pig and Palindromes -dp的更多相关文章

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

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

  2. codeforces 570 D. Tree Requests (dfs)

    题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变 ...

  3. 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 ...

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

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

  5. codeforces 570 E. Pig and Palindromes (DP)

    题目链接: 570 E. Pig and Palindromes 题目描述: 有一个n*m的矩阵,每个小格子里面都有一个字母.Peppa the Pig想要从(1,1)到(n, m).因为Peppa ...

  6. 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 coinci ...

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

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

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

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

  9. CF 570 D. Tree Requests

    D. Tree Requests http://codeforces.com/problemset/problem/570/D 题意: 一个以1为根的树,每个点上有一个字母(a-z),每次询问一个子树 ...

随机推荐

  1. PyCharm 常用习惯设置

    1.pycharm改变选中行时改行的颜色和光标所在行的颜色 1.是光标所在行的背景颜色,写代码,每写到这一行,就会是这种颜色,所以尽量改成和你代码背景颜色相近的 2.应该是旁边行号所在背景颜色 3.是 ...

  2. Linux命令小计

    一.yum和apt-get的区别 Linux系统下安装包格式有:rpm包和deb包. pm包主要应用在RedHat系列包括 Fedora等发行版的Linux系统上 deb包主要应用于Debian系列包 ...

  3. ubuntu编译opencv3.1遇到的问题

    网上有很多关于编译的具体步骤,我也是按照网上的说明一步步操作的,这里主要想记录的是在安装完之后,import cv2不存在以及其他的libopencv_hdf.so.3.1等找不到的问题,如果将这样的 ...

  4. Docker 容器(六)

    镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体.容器可以被创建.启动.停止.删除.暂停等. 容器的实质是 ...

  5. linux 查看网卡流量:sar

    sar(System Activity Reporter 系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,但我们一般用来监控网卡流量 # 安装 ...

  6. MySQL5.7 多实例

    1,先按MySQL5.7安装好后 mkdir dbdata_3307 chown mysql:mysql -R dbdata_3307 2,./bin/mysqld  --initialize --u ...

  7. Python3学习之路~2.8 文件操作实现简单的shell sed替换功能

    程序:实现简单的shell sed替换功能 #实现简单的shell sed替换功能,保存为file_sed.py #打开命令行输入python file_sed.py 我 Alex,回车后会把文件中的 ...

  8. Scala数据类型的继承结构

    Scala中,所有的值都是类对象,而所有的类,包括值类型,都最终继承自一个统一的根类型Any.统一类型,是Scala的又一大特点.更特别的是,Scala中还定义了几个底层类(Bottom Class) ...

  9. 339A

    #include <iostream> #include <string> #include <algorithm> using namespace std; #d ...

  10. NgDL:【第二周】NN基础

    1.计算图的导数计算 正向比如说是计算代价函数值,反向就是增大多少a/b/c对J的影响,也就是导数的意义,这里讲的是求导链式法则. 2.向量化 节约大量计算时间 简直是100倍的时间,看来之前实现的那 ...