P7758 [COCI2012-2013#3] HERKABE 题解
题面传送门
首先,Herkabe 老师要把前缀相同的放在一起,本蒟蒻选择采用sort的方式(大佬有更好的方法可以留言)
然后,我们就成功地将
对于求 其实很简单。
我们定义
那么我们只要求出每一组字符串的方案数,就可以知道答案了。
在上述求
递归的边界就是当当前组中的字符串数为
最后给大家康康本蒟蒻丑陋的代码
//我的码风有点奇怪
//加了点卡常的东西
//如:把 ++i 打成 i=-~i ,把 --i 打成 i=~-i
//不过认真看了前面题解的人应该能理解吧
//wjd 666
#include <cstdio>
#include <string>
#include <ctype.h>
#include <iostream>
#include <algorithm>
#define il inline
#define int long long
#define ri register int
using namespace std;
//简简单单的快读快写,其实这题可以不用,只是个人习惯而已
namespace wjd{
il int read(){
int x(0);
char ch(getchar());
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)){
x=(x<<3)+(x<<1)+(ch&15);
ch=getchar();
}
return x;
}
il void write(int x){
if(x>9) write(x/10);
putchar((x%10)|48);
}
}
using namespace wjd;
const int N=3e3+5;
const int MOD=1e9+7;
int fac[N];
string s[N];
//分治递归求解
il int work(int x,int l,int r){
if((-~l)>=r) return 1;
ri ll(l),res(1),num(1);
for(ri i=(-~l);i<r;i=-~i){
if(s[i][x]==s[ll][x]) continue;
res=res*work(-~x,ll,i)%MOD;
ll=i,num=-~num;
}
res=res*work(-~x,ll,r)%MOD;
//最后乘上全排列(阶乘)
return res*fac[num]%MOD;
}
signed main(){
int n(read());
fac[1]=1;
for(ri i(1);i<=n;i=-~i) cin>>s[i],fac[-~i]=fac[i]*(-~i)%MOD;
sort(s+1,s+n+1);
write(work(0,1,-~n));
return 0;
}
以上就是本蒟蒻对这道灰题的解法,蟹蟹观看