Description
给你三个字符串,这些字符串有些单词模糊不可认了,用”?”来代表。
现在你可以用任意英文小写字母来代表它们。要求是使得给定的三个字符串中
所有的”?”被你认定的字母代替后,各不相同且按字典序出现。问有多少种方式。
Input
先给出一个数字N,代表数据组数。
接下来3*N行,每行给出一个字符串。长度<=1000 000
Output
输出结果 Mod 10^9+9
Sample Input
3
?heoret?cal
c?mputer
?cience
jagiellonia
?niversity
kra?ow
?
b
c
Sample Output
42562
52
1
HINT
Source
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define P 1000000009
#define MAXN 1000010
#define LL long long
using namespace std;
int T,n,len[3];
char s[3][MAXN];
int c[28][28][28][4][4];//暴力预处理出转移
LL f[MAXN][4];//第一维当前位置第二维偏序关系
void init()
{
int lx,rx,ly,ry,lz,rz;
for (int i=0;i<=27;i++)
for (int j=0;j<=27;j++)
for (int k=0;k<=27;k++)
{
lx=rx=i;ly=ry=j;lz=rz=k;
if (i==27) lx=1,rx=26; if (j==27) ly=1,ry=26; if (k==27) lz=1,rz=26;
for (int l1=lx;l1<=rx;l1++)
for (int l2=ly;l2<=ry;l2++)
for (int l3=lz;l3<=rz;l3++)
for (int t=0;t<=3;t++)
{
int tmp=t;
if (t==0)
{
if (l3>l2) tmp+=1;
if (l2>l1) tmp+=2;
if (l3<l2||l2<l1) tmp=-1;
}
if (t==1)
{
if (l2>l1) tmp+=2;
if (l2<l1) tmp=-1;
}
if (t==2)
{
if (l3>l2) tmp+=1;
if (l3<l2) tmp=-1;
}
if (tmp>=0) c[i][j][k][t][tmp]++;
}
}
}
int main()
{
init();scanf("%d",&T);
while (T--)
{
n=0;f[0][0]=1;
for (int i=0;i<3;i++) scanf("%s",s[i]+1),len[i]=strlen(s[i]+1),n=max(n,len[i]);
for (int i=1;i<=n;i++) for (int j=0;j<4;j++) f[i][j]=0;
for (int i=0;i<3;i++)
for (int j=len[i]+1;j<=n;j++) s[i][j]='a'-1;
for (int i=1;i<=n;i++)
{
int x=s[0][i]-'a'+1,y=s[1][i]-'a'+1,z=s[2][i]-'a'+1;
if (x<0) x=27; if (y<0) y=27; if (z<0) z=27;
for (int j=0;j<=3;j++)
if (f[i-1][j])
for (int k=0;k<=3;k++) f[i][k]=(f[i][k]+f[i-1][j]*c[x][y][z][j][k]%P)%P;
}
printf("%lld\n",f[n][3]);
}
}