Codeforces Round #448 (Div. 2)D. String Mark(组合数学)

来源:互联网 发布:ovid数据库的网址 编辑:程序博客网 时间:2024/06/05 15:49

题目链接: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;}


阅读全文
0 0
原创粉丝点击