您的位置:首页 > 其它

JZOJ 4812 【NOIP2016提高A组五校联考2】string

2016-10-05 16:15 435 查看

string

题目大意

给出一个长度为n, 由小写英文字母组成的字符串S,求在所有由小写英文字母组成且长度为n且恰好有k位与S不同的字符串中,给定字符串T按照字典序排在第几位。

由于答案可能很大,模109+7输出。

数据范围

对于100%的数据,k<=n<=105

题解

问题转化,求有多少个字符串的字典序小于T且有k位和S不同。

我们先枚举第一位,若第一位比T1小,则第2~n位填什么字母进去都可以,用组合数求出可行方案。

若第一位等于T2,则我们枚举第二位,

有两种情况,第一种:第二位比T2小,第3~n位填什么都可以,一样用组合数求出方案数。

第二种第二位等于T2,那么我们就枚举第三位,如此类推下去到最后,求出答案即可。

Code(Pascal)

const
mo=1000000007;
var
f25,jc,ny:array[0..100000] of int64;
n,m,j,k,l,i:longint;
ch:char;
ans,kk,ff:int64;
s,t:ansistring;
function ksm(o,k:int64):int64;
begin
ksm:=1;
while k>0 do
begin
if k mod 2=1 then ksm:=ksm*o mod mo;
k:=k div 2;
o:=o*o mod mo;
end;
end;
begin
readln(n,k);
readln(s);
readln(t);
f25[0]:=1;
for i:=1 to n do
f25[i]:=(f25[i-1]*25) mod mo;
jc[0]:=1;
ny[0]:=1;
jc[1]:=1;
ny[1]:=1;
for i:=2 to n do
begin
jc[i]:=(jc[i-1]*i) mod mo;
ny[i]:=ksm(jc[i],mo-2);
end;
l:=0;
for i:=1 to n do
begin
for ch:='a' to chr(ord(t[i])-1) do
begin
kk:=l;
if ch<>s[i] then inc(kk);
kk:=k-kk;
ff:=n-i;
if (kk>=0) and (ff>=kk) then
ans:=(ans+((jc[ff]*ny[ff-kk] mod mo)*ny[kk] mod mo)*f25[kk]) mod mo;
end;
if t[i]<>s[i] then inc(l);
if l>k then break;
end;
writeln((ans+1) mod mo);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: