考慮給定兩個M、N串的情況:
定義:兩個01串
引理1:如果兩個串
證明:我們對
當
不妨設當
當
若
則我們要證
原命題得證
引理2:若
證明方法同上
然後繼續分析固定
如果
如果
如果
先考慮
如果
所以我們只需要計算
假設
我們總結下前面的推導。
令
如果
如果
否則,設
下來考慮問題的原版本
有上述分析可知,對於確定串的方案數如果
假設一開始
假設
設
對於一個確定的
在最後我們利用DP考慮下兩個串相同的方案數即可。至此,該問題結束。
第一次寫這麼長的題解,完結撒花!
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
string s;
string t;
int n;
int l1,l2;
LL pow_mod(LL a,LL e)
{
LL res=1;
for (;e;a=a*a%mod,e>>=1) if (e&1) res=res*a%mod;
return res;
}
int miu[610000];
int prim[610000],primm;
bool valid[610000];
void mobius(int N)
{
miu[1]=1;
for (int i=2;i<=N;i++)
{
if (!valid[i]) prim[++primm]=i,miu[i]=-1;
for (int j=1;j<=primm&&i*prim[j]<=N;j++)
{
valid[i*prim[j]]=1;
if (i%prim[j]==0)
{
miu[i*prim[j]]=0;
break;
}
else miu[i*prim[j]]=-miu[i];
}
}
}
LL now;
int na,nb,ma,mb,nn,mm;
LL cnt[310000],ans[310000];
LL res,all;
LL f[610000],ff[610000],inv[610000];
LL C(int n,int m)
{
LL res=(f[n]*inv[m])%mod;
res=(res*inv[n-m])%mod;
return res;
}
LL gcd(LL a,LL b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
mobius(600000);
cin>>s;
cin>>t;
cin>>n;
l1=s.size();
l2=t.size();
if (l1==l2)
{
now=1;
for (int i=0;i<l1;i++)
if (s[i]=='A')
{
if (t[i]=='A'||t[i]=='?');
else now=0;
}
else if (s[i]=='B')
{
if (t[i]=='B'||t[i]=='?');
else now=0;
}
else
{
if (t[i]=='A'||t[i]=='B');
else now=now*2%mod;
}
if (now)
{
LL tmp=(pow_mod(2,n+1)-2+mod)%mod;
tmp=tmp*tmp%mod;
res=tmp*now%mod;
}
}
for (int i=0;i<l1;i++)
if (s[i]=='A') na++;
else if (s[i]=='B') nb++;
else nn++;
for (int i=0;i<l2;i++)
if (t[i]=='A') ma++;
else if (t[i]=='B') mb++;
else mm++;
f[0]=1;
for (int i=1;i<=600010;i++)
f[i]=(f[i-1]*i)%mod;
ff[1]=ff[0]=inv[1]=inv[0]=1;
for (int i=2;i<=600010;i++)
{
inv[i]=(LL)(mod-mod/i)*inv[mod%i]%mod;
ff[i]=inv[i];
}
for (int i=2;i<=600010;i++)
inv[i]=(inv[i-1]*inv[i])%mod;
for (int i=1;i<=n;i++)
cnt[i]=LL(n/i)*(LL)(n/i);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n/i;j++)
ans[i]+=(LL)miu[j]*cnt[i*j];
all+=ans[i]*pow_mod(2,i);
all%=mod;
}
int p=na-ma,q=nb-mb+(nn-mm);
for (int i=-mm;i<=nn;i++)
{
LL tmp=C(nn+mm,mm+i);
int np=p+i,nq=q-i;
if (np==0&&nq==0) tmp=(tmp-now+mod)%mod;
if (np==nq&&np==0) res=(res+tmp*all)%mod;
else if (np<=0&&nq<=0||np>=0&&nq>=0);
else
{
int d=gcd(np,nq);
np/=d,nq/=d;
tmp=tmp*(pow_mod(2,n/max(abs(np),abs(nq))+1)-2+mod)%mod;
res=(res+tmp)%mod;
}
}
cout<<res<<endl;
return 0;
}