题目链接:http://codeforces.com/contest/895/problem/D
枚举了一晚上题意才过。。。优化的点就是因为只有一个点会发生改变,求逆元的时候可以优化一个26的常数。。。剩下的就是基本的组合数学了
为什么写的这么丑啊????
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e6+5;
const int MOD=1e9+7;
int cnt[30],tmp[30],n;
ll fac[MAXN],inv[MAXN];
char a[MAXN],b[MAXN];
ll qpow(ll a,ll b)
{
ll ans=1;a%=MOD;
for(ll i=b;i;i>>=1,a=a*a%MOD)
if(i&1)ans=ans*a%MOD;
return ans;
}
void init()
{
fac[0]=1;
for(int i=1;i<MAXN;i++)
{
fac[i]=fac[i-1]*i%MOD;
}
inv[MAXN-1]=qpow(fac[MAXN-1],MOD-2);
for(int i=MAXN-2;i>=0;i--)
{
inv[i]=inv[i+1]*(i+1)%MOD;
}
}
ll getmi(int now)
{
ll pre=1,ret=0;
for(int i=now;i<=n;i++)
{
ll I=1;
for(int j=0;j<=25;j++)
{
I=(I*inv[tmp[j]])%MOD;
}
for(int j=a[i]-'a'+1;j<=25;j++)
{
if(tmp[j])
{
ret=(ret+pre*fac[n-i]%MOD*I%MOD*fac[tmp[j]]%MOD*inv[tmp[j]-1]%MOD)%MOD;
}
}
if(!tmp[a[i]-'a'])
break;
tmp[a[i]-'a']--;
}
return ret%MOD;
}
ll getmx(int now)
{
ll ret=0;
for(int i=now;i<=n;i++)
{
ll I=1;
for(int j=0;j<=25;j++)
{
I=(I*inv[tmp[j]])%MOD;
}
for(int j=0;j<b[i]-'a';j++)
{
if(tmp[j])
{
ret=(ret+fac[n-i]%MOD*I%MOD*fac[tmp[j]]%MOD*inv[tmp[j]-1]%MOD)%MOD;
}
}
if(!tmp[b[i]-'a'])
break;
tmp[b[i]-'a']--;
}
return ret%MOD;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%s%s",a+1,b+1);
n=strlen(a+1);
init();
for(int i=1;i<=n;i++)
{
int x=a[i]-'a';
cnt[x]++;
}
ll t=0,ans;
for(int i=1;i<=n;i++)
{
if(a[i]==b[i])
{
cnt[a[i]-'a']--;
}
else
{
if(a[i]>b[i])
return 0*puts("0");
else
{
ll I=1;
for(int j=0;j<=25;j++)
{
I=(I*inv[cnt[j]])%MOD;
}
for(int j=a[i]-'a'+1;j<=b[i]-'a'-1;j++)
{
if(cnt[j])
t=(t+fac[n-i]%MOD*I%MOD*fac[cnt[j]]%MOD*inv[cnt[j]-1]%MOD)%MOD;
}
if(cnt[a[i]-'a'])
{
for(int j=0;j<=25;j++)
tmp[j]=cnt[j];
tmp[a[i]-'a']--;
t+=getmi(i+1);
t%=MOD;
}
if(cnt[b[i]-'a'])
{
for(int j=0;j<=25;j++)
tmp[j]=cnt[j];
tmp[b[i]-'a']--;
t+=getmx(i+1);
t%=MOD;
}
}
break;
}
}
ans=t%MOD;
printf("%lld\n",ans);
return 0;
}