#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; } |