#include <bits/stdc++.h>
using namespace std;
const int B=14,MSK=(1<<B)-1,MX=10010,md=1000000007;
int n,i,j,x,y,vi,mx,mx1,mx2,mxz,rev0,rev1,rev,revbase,rvb,res,cres,cx,c[4],d[4],p[4],r[4],C[MX][MX],S[MX][MX];//,saved[MX][MX];
vector<int> v[3][2];
long long cur;
char s[3][10100];
int main() {
//auto dur_beg=chrono::high_resolution_clock::now();
scanf("%d",&n);
for (i=0; i<=n; i++) {
C[i][0]=S[i][0]=1;
for (j=1; j<=i; j++) {
C[i][j]=(C[i-1][j-1]+C[i-1][j])%md;
S[i][j]=(S[i][j-1]+C[i][j])%md;
}
}
for (i=0; i<3; i++) {
scanf("%d",&r[i]);
//r[i]=1000;
scanf("%s",s[i]);
}
v[0][0]={0,1}; v[0][1]={2};
v[1][0]={0,2}; v[1][1]={1};
v[2][0]={1,2}; v[2][1]={0};
for (j=0; j<3; j++) {
x=v[j][0][0];
y=v[j][0][1];
for (cx=i=0; i<n; i++) if (s[x][i]!=s[y][i]) cx++;
//cx=334;
for (i=0; i<=cx && i<=r[x]; i++) if (cx-i<=r[y]) p[j]=(p[j]+1LL*C[cx][i]*S[n-cx][min(n-cx,min(r[x]-i,r[y]-cx+i))])%md;
}
for (i=0; i<n; i++) if (s[0][i]==s[1][i]) {
if (s[0][i]==s[2][i]) c[3]++; else c[0]++;
} else if (s[0][i]==s[2][i]) c[1]++; else c[2]++;
/*c[0]=333;
c[1]=333;
c[2]=333;
c[3]=1;*/
mx=min(c[0],min(r[0],r[1]));
int ins=0,outs=0;
for (rev0=max(0,c[0]-r[2]); rev0<=mx; ++rev0) {
//if ((rev0&127)==0) printf("rev0 = %d\n",rev0);
mx1=min(c[1],min(r[0]-rev0,r[2]-c[0]+rev0));
for (rev1=max(0,c[1]-r[1]+rev0); rev1<=mx1; ++rev1) {
d[0]=rev0+rev1;
d[1]=rev0+c[1]-rev1;
d[2]=c[0]-rev0+rev1;
mxz=min(r[1]-d[1],r[2]-d[2]);
mx2=min(c[2],mxz);
cur=(1LL*C[c[0]][rev0]*C[c[1]][rev1])%md;
revbase=c[2]-r[0]+d[0];
rev=max(0,revbase);
if (rev>mx2) continue;
//if (!saved[rev][mx2]) {
mxz-=rev;
rvb=rev-revbase;
for (cres=0; rev<=mx2; ++rev, --mxz, ++rvb) {
cx=min(c[3],mxz);
cx=min(cx,rvb);
//if (cx==c[3])
if (cx>=0) cres=(cres+1LL*C[c[2]][rev]*S[c[3]][cx])%md;
}
res=(res+cur*cres)%md;
// saved[rev][mx2]=cres+1;
// ++ins;
// } else {
// res=((res+cur*saved[rev][mx2])%md+cur*(md-1LL))%md;
//++outs;
// }
}
// printf("%d %d\n",ins,outs);
}
x=res;
//printf("%d\n",res);
//for (j=0; j<3; j++) printf("%d %d\n",p[j],int(S[n][r[j]]));
for (j=0; j<3; j++) {
p[j]=(p[j]+md-x)%md;
res=(res+1LL*S[n][r[j]]+md-p[j]+md-x)%md;
}
printf("%d\n",res);
/* auto dur=chrono::high_resolution_clock::now()-dur_beg;
auto ms=chrono::duration_cast<chrono::milliseconds>(dur).count();
fprintf(stderr,"%d ms\n",ms);
fflush(stderr);*/
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include <bits/stdc++.h> using namespace std; const int B=14,MSK=(1<<B)-1,MX=10010,md=1000000007; int n,i,j,x,y,vi,mx,mx1,mx2,mxz,rev0,rev1,rev,revbase,rvb,res,cres,cx,c[4],d[4],p[4],r[4],C[MX][MX],S[MX][MX];//,saved[MX][MX]; vector<int> v[3][2]; long long cur; char s[3][10100]; int main() { //auto dur_beg=chrono::high_resolution_clock::now(); scanf("%d",&n); for (i=0; i<=n; i++) { C[i][0]=S[i][0]=1; for (j=1; j<=i; j++) { C[i][j]=(C[i-1][j-1]+C[i-1][j])%md; S[i][j]=(S[i][j-1]+C[i][j])%md; } } for (i=0; i<3; i++) { scanf("%d",&r[i]); //r[i]=1000; scanf("%s",s[i]); } v[0][0]={0,1}; v[0][1]={2}; v[1][0]={0,2}; v[1][1]={1}; v[2][0]={1,2}; v[2][1]={0}; for (j=0; j<3; j++) { x=v[j][0][0]; y=v[j][0][1]; for (cx=i=0; i<n; i++) if (s[x][i]!=s[y][i]) cx++; //cx=334; for (i=0; i<=cx && i<=r[x]; i++) if (cx-i<=r[y]) p[j]=(p[j]+1LL*C[cx][i]*S[n-cx][min(n-cx,min(r[x]-i,r[y]-cx+i))])%md; } for (i=0; i<n; i++) if (s[0][i]==s[1][i]) { if (s[0][i]==s[2][i]) c[3]++; else c[0]++; } else if (s[0][i]==s[2][i]) c[1]++; else c[2]++; /*c[0]=333; c[1]=333; c[2]=333; c[3]=1;*/ mx=min(c[0],min(r[0],r[1])); int ins=0,outs=0; for (rev0=max(0,c[0]-r[2]); rev0<=mx; ++rev0) { //if ((rev0&127)==0) printf("rev0 = %d\n",rev0); mx1=min(c[1],min(r[0]-rev0,r[2]-c[0]+rev0)); for (rev1=max(0,c[1]-r[1]+rev0); rev1<=mx1; ++rev1) { d[0]=rev0+rev1; d[1]=rev0+c[1]-rev1; d[2]=c[0]-rev0+rev1; mxz=min(r[1]-d[1],r[2]-d[2]); mx2=min(c[2],mxz); cur=(1LL*C[c[0]][rev0]*C[c[1]][rev1])%md; revbase=c[2]-r[0]+d[0]; rev=max(0,revbase); if (rev>mx2) continue; //if (!saved[rev][mx2]) { mxz-=rev; rvb=rev-revbase; for (cres=0; rev<=mx2; ++rev, --mxz, ++rvb) { cx=min(c[3],mxz); cx=min(cx,rvb); //if (cx==c[3]) if (cx>=0) cres=(cres+1LL*C[c[2]][rev]*S[c[3]][cx])%md; } res=(res+cur*cres)%md; // saved[rev][mx2]=cres+1; // ++ins; // } else { // res=((res+cur*saved[rev][mx2])%md+cur*(md-1LL))%md; //++outs; // } } // printf("%d %d\n",ins,outs); } x=res; //printf("%d\n",res); //for (j=0; j<3; j++) printf("%d %d\n",p[j],int(S[n][r[j]])); for (j=0; j<3; j++) { p[j]=(p[j]+md-x)%md; res=(res+1LL*S[n][r[j]]+md-p[j]+md-x)%md; } printf("%d\n",res); /* auto dur=chrono::high_resolution_clock::now()-dur_beg; auto ms=chrono::duration_cast<chrono::milliseconds>(dur).count(); fprintf(stderr,"%d ms\n",ms); fflush(stderr);*/ return 0; } |
English