F. Palindrome

Problem Description

A string is palindrome if it can be read the same way in either direction, for example “maram” is palindrome, while “ammar” is not.

You are given a string of n characters, where each character is either a lowercase English letter or a question mark (?). You are also given a set of m constraints. Your task is to count the number of ways in which we can replace all question marks with lowercase English letters such that the resulting string is a palindrome that does not violate the given constraints.

The constraints are in the form of pairs of indices of letters that should be the same.

Input

The first line of input contains one integer T, the number of test cases (1 ≤ T ≤ 256).

Each test case begins with two integers: n representing the string size (1 ≤ n ≤ 50000) and m representing the number of constraints (0 ≤ m ≤ 10000).

The next line contains a string of length n. The next m lines, each contains two integers x and y (1 <= x < y <= n), where letters at index x and index y must be the same.

Test cases are separated by a blank line.

Output

For each test case, print the number of ways modulo 1,000,000,007 (10^9 + 7).

Sample Input

4

5 1

ma??m

1 5

5 4

ma??m

1 2

1 5

1 3

3 4

7 0

acm?cpc

4 1

????

1 4

Sample Output

26

0

0

676


解题心得:

  1. 这个题的题意就是给你一个字符串,里面包含小写字母和?,字符串必须是回文串并且给你m对数,该数位置对应的字母应该相等。?可以替换成任意的26个小写字母,问一共有多少种形成规定回文串的可能。
  2. 在做这个题的时候是比赛,比赛很简单,这个题是最后一个,没想到是一个简单的带权并查集,当时在用搜索硬怼,写了一大堆代码,很恼火,还是不够冷静啊。
  3. 就这个题来说如果细分很麻烦,又是回文又是位置对应还有?替换。其实思维到位了就完全不用那么麻烦,直接将该合并的合并,回文位置合并,对应位置合并,合并之后在从根节点开始找,看同一个根的集合里面的元素,如果不对应,不回文的直接输出0就行了,只有该集合全部是?的才可以用answer乘以26(因为一个集合里面的?必须相等)。每一个集合里面的字母必须全部相等,或者全是?。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e4+100;
const int MOD = 1e9+7;
char s[maxn];
int father[maxn];
vector <int> ve[maxn]; int find(int x)
{
if(father[x] == x)
return x;
else
return father[x] = find(father[x]);
} int main()
{
int len,m;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&len,&m);
for(int i=0; i<=len; i++)
{
father[i] = i;
ve[i].clear();
}
scanf("%s",s); //对应位置的不用管直接合并
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
a--,b--;
int fa = find(a);
int fb = find(b);
if(fa != fb)
father[fa] = fb;
}
int Len = len / 2; //回文位置的不用管也直接合并
for(int i=0; i<len; i++)
{
int fa = find(i);
int fb = find(len-1-i);
if(fa!=fb)
father[fa] = fb;
} bool flag = false;//用来记录是否是符合规定的回文串 //同一根节点的集合全部记录下来
for(int i=0; i<len; i++)
{
int f = find(i);
ve[f].push_back(i);
} long long ans = 1;
for(int i=0; i<len; i++)
{
char c = 'A',cnt = 0;
Len = ve[i].size();
if(!Len)
continue;
for(int j=0; j<Len; j++)
{
if(s[ve[i][j]] == '?')//该集合里面的?的数目记录一下
cnt++;
else if(s[ve[i][j]] != c && c == 'A')//记录该集合里面的字幕
c = s[ve[i][j]];
else if(s[ve[i][j]] != c && c != 'A')//一个集合里面出现了两种不同的字母,不符合要求
flag = true;
} if(Len == cnt)//一个集合里面全是?(所有?必须替代成同一个字母)
{
ans = (ans * 26)%MOD;
}
}
if(flag)
{
printf("0\n");
continue;
}
printf("%d\n",ans);
}
}

最新文章

  1. 说一说python的牛比与不爽
  2. SQL Server 2008 R2——统计各部门某年入职人数
  3. POJ 2151 概率DP
  4. Android软键盘弹出时布局问题
  5. C# 字符串驻留池
  6. HDU 1509 Windows Message Queue(队列)
  7. 权限认证 cookie VS token
  8. JavaScript 对象JavaScript 对象
  9. CentOS 7 安装Redis4.0
  10. PhoenixFD插件流体模拟——UI布局【Dynamics】详解
  11. windows server 2008 R2安装图片浏览器/照片查看器方法
  12. 关于SVM(support vector machine)----支持向量机的一个故事
  13. centos 7 安装搜狗输入法
  14. BUILDING ANGULAR APPS USING FLUX ARCHITECTURE
  15. Django 分页查询并返回jsons数据,中文乱码解决方法
  16. sql server query to get the list of column name in a table
  17. JZOJ.5273【NOIP2017模拟8.14】亲戚
  18. 【BZOJ2259】[Oibh]新型计算机 最短路
  19. [PATCH] ARM: add dtbImage.&lt;dt&gt; and dtbuImage.&lt;dt&gt; rules
  20. 解决 div或者a标签的高度比里面的img高度多的 问题

热门文章

  1. JS中void(0)的含义
  2. 使用js获取复选框的值,并把数组传回后台处理,过程使用的是Ajax异步查询
  3. vuejs vue-resource post方式提交参数PHP $_POST获取不到
  4. Windows系统下查看文件编码类型
  5. jsp四大作用域之Session
  6. 【转载】Python实现图书馆预约功能
  7. python基础教程总结13——网络编程,
  8. Python-OpenCV中的cv2.inpaint()函数
  9. Jquery库插件大全(工作中遇到总结)
  10. 跑yscacaca/HHAR-Data-Process出现的问题