题解
推荐wxh
可爱的修修
本题相较于CF794G,n加0了。
我们需要快速计算
∑ni=1∑nj=12(i,j)
∑nd=12d∑n/di=1∑n/dj=1[(i,j)=1]
∑nd=12d∗(2∗∑n/di=1ϕ(i)−1)
分块杜教筛即可。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int maxn=300000+10,maxd=5000000+10,maxha=maxd*5,mo=1000000007,inv2=(mo+1)/2;
char a[maxn],b[maxn];
int fac[maxn*2],inv[maxn*2];
int pri[maxd],phi[maxd],gg[maxd],ha[maxha+100][2];
bool bz[maxd];
int i,j,k,l,r,t,m,lena,lenb,d,da,db,dda,ddb,p,q,c,cnt,ans,top;
ll n,N,nn;
bool czy;
int qsm(int x,ll y){
if (!y) return 1;
int t=qsm(x,y/2);
t=(ll)t*t%mo;
if (y%2) t=(ll)t*x%mo;
return t;
}
int S(int n){
return (ll)n*(n+1)%mo*inv2%mo;
}
int getha(ll n){
int k=(n-1)%maxha+1;
while (ha[k][0]!=n&&ha[k][0]!=0) k=(k==maxha)?1:k+1;
return k;
}
int getphi(ll n){
if (n<=maxd-10) return phi[n];
int k=N/n;
if (gg[k]) return gg[k];
ll i=2,j;
int t=S(n%mo),l;
while (i<=n){
j=n/(n/i);
l=getphi(n/i);
(t-=(ll)((j-i+1)%mo)*l%mo)%=mo;
i=j+1;
}
return gg[k]=t;
}
void prepare(){
fac[0]=1;
fo(i,1,m) fac[i]=(ll)fac[i-1]*i%mo;
inv[m]=qsm(fac[m],mo-2);
fd(i,m-1,0) inv[i]=(ll)inv[i+1]*(i+1)%mo;
phi[1]=1;
fo(i,2,maxd-10){
if (!bz[i]){
phi[i]=i-1;
pri[++top]=i;
}
fo(j,1,top){
if ((ll)i*pri[j]>maxd-10) break;
bz[i*pri[j]]=1;
if (i%pri[j]==0){
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
fo(i,1,maxd-10) (phi[i]+=phi[i-1])%=mo;
/*fo(i,1,n){
t=qsm(2,i);
l=(2*phi[n/i]-1)%mo;
(c+=(ll)t*l%mo)%=mo;
}*/
l=1;
ll i=1,j;
while (i<=n){
j=n/(n/i);
r=(qsm(2,j+1)-1)%mo;
(c+=(ll)(r-l)*((2*getphi(n/i)-1)%mo)%mo)%=mo;
l=r;
i=j+1;
}
}
int C(int n,int m){
if (n<m||m<0) return 0;
return (ll)fac[n]*inv[m]%mo*inv[n-m]%mo;
}
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int main(){
//freopen("data.in","r",stdin);
scanf("%s",a+1);
lena=strlen(a+1);
scanf("%s",b+1);
lenb=strlen(b+1);
m=lena+lenb;
scanf("%lld",&n);
N=n;
prepare();
fo(i,1,lena)
if (a[i]=='A') da++;
else if (a[i]=='B') db++;
else p++;
fo(i,1,lenb)
if (b[i]=='A') da--;
else if (b[i]=='B') db--;
else q++;
fo(d,-q,p){
t=C(p+q,q+d);
dda=da+d;ddb=db+p-q-d;
if (dda==0&&ddb==0){
(ans+=(ll)t*c%mo)%=mo;
continue;
}
if ((ll)dda*ddb<0){
dda=abs(dda);ddb=abs(ddb);
nn=(ll)n/(max(dda,ddb)/gcd(dda,ddb))+1;
nn=(qsm(2,nn)-2)%mo;
(ans+=(ll)t*nn%mo)%=mo;
}
}
if (lena==lenb){
czy=1;
cnt=0;
fo(i,1,lena)
if (a[i]=='?'&&b[i]=='?') cnt++;
else if (a[i]!='?'&&b[i]!='?'&&a[i]!=b[i]){
czy=0;
break;
}
if (czy){
(ans-=(ll)qsm(2,cnt)*c%mo)%=mo;
c=(qsm(2,n+1)-2)%mo;
c=(ll)c*c%mo;
(ans+=(ll)qsm(2,cnt)*c%mo)%=mo;
}
}
(ans+=mo)%=mo;
printf("%d\n",ans);
}