895D
来源:互联网 发布:淘宝怎么看别人日销量 编辑:程序博客网 时间:2024/06/05 06:27
给你串a串b,问用a的排列生成新串c满足字典序a<c<b的串c种类数
问题转化成问f(s),表示用已有字符构建的字符串字典序上小于s,答案就是f(b)-f(a)-1
这样一转化就不用枚举两个字典序变化点了。。
然后i枚举字典序变化点,j枚举字符集
由于字典序变化点越靠后贡献越小,所以维护一个cur表示当前可用字符生成的不同字符串个数,
每当决定一个字符,cur就要除掉剩下字符的个数,再乘上这个要用的字符的剩余个数
#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) #define sqr(a) (a)*(a)const int inf=0x3f3f3f3f;const int maxn=1e6+5;const int mod=1e9+7;int n;char a[maxn],b[maxn];int cnt[26],c[26];int fac[maxn],rfac[maxn],save_rev[maxn];int f(char *s){memcpy(c,cnt,sizeof c);int cur=fac[n];for(int i=0;i<26;i++){if(c[i])cur=1ll*cur*rfac[c[i]]%mod;}//cur是剩下字符可构成字符串种数int ans=0;for(int i=1;i<=n;i++){//枚举不同位置for(int x=0;x<s[i]-'a';x++){if(c[x]){//枚举比他小的字符int now=cur;now=1ll*now*save_rev[n-i+1]%mod;//选定一种字符now=1ll*now*c[x]%mod;//选哪一个ans=(ans+now)%mod;}}if(c[s[i]-'a']){cur=1ll*cur*save_rev[n-i+1]%mod;cur=1ll*cur*c[s[i]-'a']%mod;c[s[i]-'a']--;}else{break;}}return ans;}int rev(int a){int ret=1;for(int b=mod-2;b;b>>=1,a=(ll)a*a%mod)if(b&1)ret=(ll)ret*a%mod;return ret;}int main(){fac[0]=rfac[0]=1;for(int i=1;i<maxn;i++){fac[i]=(ll)i*fac[i-1]%mod;save_rev[i]=rev(i);rfac[i]=(ll)save_rev[i]*rfac[i-1]%mod;}scanf("%s%s",a+1,b+1);n=strlen(a+1);for(int i=1;i<=n;i++){cnt[a[i]-'a']++;}printf("%d\n",(f(b)-f(a)-1+mod)%mod);}
阅读全文
0 0
- 895D
- codeforces 895D
- d
- d
- d
- d
- d
- D
- d
- d
- d
- d
- d
- %d
- d
- d
- d
- D
- 17.12.6日报
- LeetCode 55. Jump Game
- C语言的经典面试题
- 写给自己的第一篇博客
- sublime text 3 中文位置偏下解决方法
- 895D
- Create a .desktop file that opens and execute a command in a terminal
- C和指针之高级指针话题通过函数指针实现在链表中找到特定的值
- mysql近500w条数据建立索引后查询速度还是提升很多
- HDU 5550 Game Rooms (dp+前缀和预处理)
- JingS-5
- Sql语句 读取Excel
- 临时内核页表的建立过程
- 单点登录原理与简单实现