(Combinatorics)
meaning of the questions: Given two strings consisting of letters in English
Ideas:
First, statistics
The first number is better requirements, obtained directly
In the first of several aligned itself seeking process, with
(Formula too lazy to write .. This editor will use a little less. Words, or to knock title, although this topic and ideas out, knock thief slow ...)
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
const int maxn = 1000010;
const LL mod = 1e9 + 7;
bool s2_smaller, s2_bigger;
int num[30], sum[30];
char s1[maxn], s2[maxn];
LL fac[maxn], inv_fac[maxn];
LL pow(LL a, LL b) {
LL ret = 1;
while(b) {
if(b&1)
ret = ret * a % mod;
a = a * a % mod;
b >>= 1;
}
return ret;
}
void pre_treat(int len) {
fac[0] = inv_fac[0] = 1;
for(int i=1; i<=len; i++) {
fac[i] = (LL)i * fac[i-1] % mod;
inv_fac[i] = pow((LL)fac[i], mod-2);
}
}
void init(int len) {
for(int i=0; i<len; i++)
num[s1[i]-'a'] ++;
sum[0] = num[0];
for(int i=1; i<26; i++)
sum[i] = sum[i-1] + num[i];
}
void transform_s2(int len) {
init(len);
for(int i=0; i<len; i++) {
int alpha = s2[i] - 'a';
if(!s2_smaller && !s2_bigger) {
if(num[alpha])
num[alpha] --;
else {
for(int j=alpha-1; j>=0; j--) if(num[j]) {
s2_smaller = true; //puts("small");
s2[i] = j + 'a'; num[j] --;
break ;
}
if(s2_smaller) continue ;
for(int j=alpha+1; j<26; j++) if(num[j]) {
s2_bigger = true; //puts("big");
s2[i] = j + 'a'; num[j] --;
break ;
}
if(s2_bigger) continue ;
}
}
else if(s2_smaller) {
for(int j=25; j>=0; j--) if(num[j]) {
s2[i] = j + 'a'; num[j] --;
break ;
}
}
else {//s2_bigger
for(int j=0; j<26; j++) if(num[j]) {
s2[i] = j + 'a'; num[j] --;
break ;
}
}
}
}
LL solve(char *s, int len) {
init(len);
LL ret = 0;
for(int i=0; i<len; i++) {
int alpha = s[i] - 'a';
if(alpha > 0 && sum[alpha-1] > 0) {
LL t1 = fac[len-i-1], t2 = 0;
for(int j=0; j<26; j++) if(num[j]) {
t1 = t1 * inv_fac[num[j]] % mod;
if(j < alpha)
t2 = (t2 + num[j]) % mod;
}
ret = (ret + t1 * t2 % mod) % mod;
}
//printf("------i:%d ret:%I64d\n",i,ret);
num[alpha] --;
for(int j=alpha; j<26; j++)
sum[j] --;
}
return ret;
}
int main() {
//freopen("test.txt","r",stdin);
s2_smaller = s2_bigger = false;
scanf("%s%s",s1,s2);
int len = strlen(s1);
pre_treat(len);
transform_s2(len);
LL l = solve(s1, len), r = solve(s2, len);
//printf("l:%I64d r:%I64d\n",l,r);
LL ans = (r - l + mod) % mod;
if(!s2_smaller && !s2_bigger)
ans = (ans - 1 + mod) % mod;
else if(s2_smaller)
ans = ans;
else
ans = (ans - 1 + mod) % mod;
printf("%I64d\n",ans);
return 0;
}