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
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
ACM Arabella Collegiate Programming Contest 2015
题意:给你一个字符串,串中只能出现小写字母和‘?’。'?'可以代替任何小写字母。现在给你m对(x,y),必须使得第x个字符和第y个字符相同,并且该字符串必须为回文串。现在问组成回文串的方案数。
分析:并查集。利用并查集把相关的字符关联起来,三种情况:如果关联的字符都为'?',ans=ans*26%mod;如果关联的字符出现了不相同的字符,那么直接输出0即可;如果关联字符出现的字符都相同(可存在'?'),那么’?‘只能是变成该种字符了,即ans不变,或ans=ans*1。
题目链接:http://codeforces.com/gym/100676
代码清单:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 50000 +5;
int T,n,m,x,y;
int pos,len;
bool judge;
char str[maxn];
int father[maxn];
ll ans,vis[maxn];
int Find(int x){
if(x!=father[x]) return Find(father[x]);
return father[x];
}
void add(int x,int y){
x=Find(x);
y=Find(y);
if(x!=y) father[y]=x;
}
void init(){
memset(vis,0,sizeof(vis));
for(int i=0;i<=len;i++)
father[i]=i;
for(int i=0;i<len/2;i++)
add(i,len-i-1);
judge=true;
ans=1;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
scanf("%s",str);
len=strlen(str);
init();
for(int i=0;i<m;i++){
scanf("%d%d",&x,&y);
add(x-1,y-1);
}
for(int i=0;i<len;i++){
pos=Find(i);
if(str[pos]!='?'){
if(str[i]=='?') vis[pos]=1;
else if(str[i]!=str[pos]){
judge=false;
break;
}
}
else{
if(str[i]=='?') vis[pos]=26;
else{
str[pos]=str[i];
vis[pos]=1;
}
}
}
if(!judge) printf("0\n");
else{
for(int i=0;i<len;i++){
pos=Find(i);
if(vis[pos]==26){
ans=ans*26%mod;
vis[pos]=1;
}
}
printf("%I64d\n",ans);
}
}return 0;
}