Description
给出一个长度为n, 由小写英文字母组成的字符串S, 求在所有由小写英文字母组成且长度为n 且恰好有k 位与S 不同的字符串中,给定字符串T 按照字典序排在第几位。
由于答案可能很大,模10^9 + 7 输出。
Solution
枚举一个
i
,表示当前做到第
1. 当
Ti>Si
时,意味着目标串当前位可能包含判定串,所以分成两条式子,分别计算当前位置相等与不相等的情况。
2. 当
Ti=Si
时,意味着目标串当前位最多等于判定串,而因为当等于时,后续操作能够处理到,所以只用计算不相等是的贡献。
3. 当
Ti<Si
时,与上述情况相似,只是略有一点不同。
很简单也很好想,但是我调了一下午。
Code
const mo=1000000007;
var
c,mi,ni,s,t:array[0..100000] of int64;
n,m,i:longint;
ans:int64;
st:ansistring;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function ksm(x,y:longint):int64;
begin
if y=0 then exit(1);
if y=1 then exit(x mod mo);
if y mod 2=0 then exit(sqr(ksm(x,y div 2))mod mo)
else exit(x*ksm(x,y-1)mod mo);
end;
begin
readln(n,m);
c[0]:=1;mi[0]:=1;
for i:=1 to n do c[i]:=(c[i-1]*i)mod mo;
for i:=1 to n do mi[i]:=(mi[i-1]*25)mod mo;
ni[n]:=ksm(c[n],mo-2);
for i:=n-1 downto 0 do ni[i]:=ni[i+1]*(i+1) mod mo;
readln(st);
for i:=1 to n do t[i]:=ord(st[i])-96;
readln(st);
for i:=1 to n do s[i]:=ord(st[i])-96;
for i:=1 to n do
begin
if m=0 then break;
if s[i]=t[i] then
begin
ans:=(ans+max(0,s[i]-1)*mi[m-1] mod mo*c[n-i] mod mo*ni[m-1] mod mo*ni[n-i-m+1] mod mo)mod mo;
end;
if s[i]>t[i] then
begin
ans:=(ans+max(0,s[i]-2)*mi[m-1] mod mo*c[n-i] mod mo*ni[m-1] mod mo*ni[n-i-m+1] mod mo)mod mo;
if n-i-m<0 then
begin
dec(m);
continue;
end;
ans:=(ans+mi[m]*c[n-i] mod mo*ni[m] mod mo*ni[n-i-m] mod mo)mod mo;
dec(m);
end;
if s[i]<t[i] then
begin
if n-i-m+1<0 then
begin
dec(m);
continue;
end;
ans:=(ans+max(0,s[i]-1)*mi[m-1] mod mo*c[n-i] mod mo*ni[m-1] mod mo*ni[n-i-m+1] mod mo)mod mo;
dec(m);
end;
end;
writeln(ans+1);
end.