Problem D:

题意:给定一棵n个点树,每个点有一个字母,有m个询问,每次询问某个节点x的子树中所有深度为k的点能否组成一个回文串

分析:一堆点能组成回文串当且仅当数量为奇数的字母不多于1个,显然这个状态可以用二进制表示

那么对于单个询问如何快速找到所有符合要求的点呢?

这里可以考虑树的dfs序,我们把深度相同的点按照dfs序加入集合中,易知在同一颗子树中的点肯定形成了一个连续的区间。

因此每次可以通过二分子树根节点的进入dfs序的时间和出dfs序的时间来找到这个区间

找到区间后可以根据预处理出的异或前缀和直接得到这个区间的二进制状态,再check一下即可

复杂度 n+m*(logn+26)

代码:

 #include <bits/stdc++.h>
using namespace std;
vector<int>g[];
int a[];
char s[];
int in[];
int out[];
int n,m;
int t=;
struct node
{
int t,val;
bool operator <(const node &a)const
{
return t<a.t;
}
};
vector<node>ans[];
void dfs(int now,int d)
{
in[now]=++t;
ans[d].push_back(node{t,ans[d][ans[d].size()-].val^a[now]});
for(int i=;i<(int)g[now].size();i++)
{
int to=g[now][i];
dfs(to,d+);
}
out[now]=++t;
}
int main()
{
scanf("%d%d",&n,&m); for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
g[x].push_back(i);
} scanf("%s",s);
for(int i=;i<=n;i++)
{
a[i]=<<(s[i-]-'a');
ans[i].push_back(node{,});
}
dfs(,);
while(m--)
{
int p,x;
scanf("%d%d",&p,&x);
auto l=lower_bound(ans[x].begin(),ans[x].end(),node{in[p],});
auto r=upper_bound(ans[x].begin(),ans[x].end(),node{out[p],});
l--;
r--;
int st=((*l).val)^((*r).val);
int cnt=;
for(int i=;i<;i++)
{
if(st&(<<i))
cnt++;
}
if(cnt>)
{
puts("No");
}
else
{
puts("Yes");
}
}
return ;
}

Problem E:

题意:给一个n*m的棋盘,每个格子有一个字母,现在从1,1走到n,m,每次只能向右或者向下走,问走的路径上形成的字符串是回文串的方案书是多少

分析:从回文串的中点,即x+y=(n+m)/2的地方开始dp ,dp[i][j][k]存储当前回文长度为2*i ,左端点的x为i,右端点的x为j的回文串有多少个。

然后按照对角线递推即可。转移时注意必须满足左端点的x必须小于右端点,y必须大于右端点

代码:

 #include <bits/stdc++.h>
using namespace std;
int n,m;
int dp[][][];
char s[][];
const int mod=1e9+;
int main()
{
scanf("%d%d",&n,&m);
for(int i=; i<n; i++)
{
scanf("%s",s[i]);
}
int ok=;
for(int i=(n+m)/-; i>=; i--)
{
memset(dp[i%],,sizeof(dp[i%]));
int j=n+m--i;
for(int x1=; x1<n; x1++)
{
int y1=i-x1;
if(y1<||y1>=m)
continue;
for(int x2=; x2<n; x2++)
{ int y2=j-x2;
if(y2<||y2>=m)
continue;
if(x1>x2||y1>y2)
continue;
if(s[x1][y1]==s[x2][y2])
{
if(ok==)
{
dp[i%][x1][x2]=;
continue;
}
for(int a=; a<; a++)
{
if(x1+a>=n)
continue;
for(int b=-; b<; b++)
{
if(x2+b<)
continue;
dp[i%][x1][x2]=(dp[i%][x1][x2]+dp[(i+)%][x1+a][x2+b])%mod;;
}
}
}
}
}
ok++;
}
printf("%d\n",dp[][][n-]);
return ;
}

Codeforces Round #316 (Div. 2) D、E的更多相关文章

  1. Codeforces Round #437 (Div. 2)[A、B、C、E]

    Codeforces Round #437 (Div. 2) codeforces 867 A. Between the Offices(水) 题意:已知白天所在地(晚上可能坐飞机飞往异地),问是否从 ...

  2. Codeforces Round #298 (Div. 2) A、B、C题

    题目链接:Codeforces Round #298 (Div. 2) A. Exam An exam for n students will take place in a long and nar ...

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

    C. Replacement Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/570/proble ...

  4. Codeforces Codeforces Round #316 (Div. 2) C. Replacement 线段树

    C. ReplacementTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/570/problem ...

  5. Codeforces Round #482 (Div. 2) C 、 Kuro and Walking Route(dfs)979C

    题目链接:http://codeforces.com/contest/979/problem/C 大致题意 给出n个点,有n-1个边将他们链接.给出x,y,当某一路径中出现x....y时,此路不通.路 ...

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

    题意:给定一个字符串,里面有各种小写字母和' . ' ,无论是什么字母,都是一样的,假设遇到' . . ' ,就要合并成一个' .',有m个询问,每次都在字符串某个位置上将原来的字符改成题目给的字符, ...

  7. 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了. 总结:下次一定要注意了,提交前一定要看 ...

  8. Codeforces Round #604 (Div. 2) D、E、F题解

    Beautiful Sequence Beautiful Mirrors Beautiful Bracket Sequence (easy version) Beautiful Sequence \[ ...

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

    题:https://codeforces.com/contest/570/problem/D 题意:给定一个以11为根的n个节点的树,每个点上有一个字母(a~z),每个点的深度定义为该节点到11号节点 ...

随机推荐

  1. 第四章:使用Proxy代理让客户端服务端分工合作。

    <基于1.8 Forge的Minecraft mod制作经验分享> 别被那个Proxy代理吓到,很简单的. 我们先讨论为什么要用Proxy代理: 像打开新的UI这种操作,比如打开一个背包, ...

  2. 配置NTP时间服务器

    一.安装ntp软件 1.检查是否安装了ntp相关包. rpm -qa | grep ntp 2.安装ntp软件. yum -y install ntp 二.参数讲解 ignore  :关闭所有的 NT ...

  3. systemd添加自定义系统服务设置自定义开机启动

    1.服务权限 systemd有系统和用户区分:系统(/user/lib/systemd/system/).用户(/etc/lib/systemd/user/).一般系统管理员手工创建的单元文件建议存放 ...

  4. LVM命令摘要

      命令 描述 物理卷(PV) pvcreate 创建LVM磁盘     #pvcreate /dev/sdb pvdisplay 显示卷组中的物理卷信息 pvchange 设置PV的性能,允许或拒绝 ...

  5. 九度OJ 1552座位问题(dp)

    刚开始写的一维数组,但是由于后面的数字较大,要对它取模,所以用一维数组进行减法运算,结果就不对了.所以还是得用二维数组,用dp[n][0]来表示第n位为男生总的方法个数,dp[n][1]表示第n位为女 ...

  6. IO-文件 File 复制 读写 总结

    一定要注意: 传入的参数,应该是包含文件名的完整路径名,不能把一个文件复制到[文件夹]中,因为[文件夹]本身是不能有输入输出流的,只能复制到一个[文件]中,否则会报异常. 以字节流读写的三种方式 pu ...

  7. 06-自定义Attribute标记案例

    自定义Attribute: 1)Attribute都从System. Attribute类继承,类名一般以Attribute结尾 2) 标记类的用途—AttributeUsage标记(标记的标记):A ...

  8. jQuery 基本实现功能模板

    下面是列出了基本功能的实现 <!DOCTYPE html> <html> <head> <script src="http://libs.baidu ...

  9. core java 第四章笔记

    import java.util.*; public class Employee { private static int nextid = 1; private String name; priv ...

  10. 你好,C++(27)在一个函数内部调用它自己本身 5.1.5 函数的递归调用

    5.1.5 函数的递归调用 在函数调用中,通常我们都是在一个函数中调用另外一个函数,以此来完成其中的某部分功能.例如,我们在main()主函数中调用PowerSum()函数来计算两个数的平方和,而在P ...