链接:http://codeforces.com/gym/100676/attachments/download/3333/acm-arabella-collegiate-programming-contest-en.pdf
题目:F - F. Palindrome
题意:给你一个字符串,?处是没有填的地方,然后他是一个回文串并且告诉你一些其他位置的字母是需要相等的。问你:有多少种满足条件的填法。
分析:这题比较简洁的做法就是并差集。首先把所有能够确定的?确定了,再考虑不能确定的?的个数,其实就是用并差集集合并集合。优先吧字母作为根节点,处理后如果一个集合的根节点是?,那么这个集合里所有的元素都不确定,而且它们取同一个字母,不确定的?+1.
注意:没有?时是1,只是隐含在黑暗处的Bug.
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int mod=1000000007; const int maxn=50010; char s[maxn]; int f[maxn]; int n,m,x,y,sum,t,len,ff; long long ans; int find(int x){ return (f[x]==x?x:f[x]=find(f[x])); } void cal(int x,int y) { if(s[x] == s[y]) f[x]=y; else if(s[x] == '?') f[x]=y; else if(s[y] == '?') f[y]=x; else ff=1; } int init() { int ans=0; ff=0; len=strlen(s); for(int i=0;i<len;i++) f[i]=i; for(int i=0,j=len-1;i<j;i++,j--) cal(i,j); for(int i=0;i<m;i++){ scanf("%d %d",&x,&y); cal(find(--x),find(--y)); } if(ff==1) return -1; for(int i=0;i<len;i++) if(s[i]=='?' && f[i]==i) ans++; return ans; } int main() { scanf("%d",&t); while(t--) { scanf("%d%d%s",&n,&m,&s); sum = init(); if(sum<1) {printf("%d\n",sum+1);continue;} ans=1; for(int i=0;i<sum;i++) ans = (ans*26)%mod; printf("%lld\n",(ans+mod)%mod); } return 0; }