[hiho1579] Reverse Suffix Array [ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 B]

来源:互联网 发布:mac版premiere出gif 编辑:程序博客网 时间:2024/06/05 06:32

题意

给出一个字符串后缀的排序,求可能的原串个数
例如”banana”的后缀排序为[6,4,2,1,5,3]
因为

6:a4:ana2:anana1:b5:na3:nana

题解

以样例为例

Index : 1 2 3 4 5 6String: b a n a n aRank  : 4 3 6 2 5 1Pos   : 6 4 2 1 5 3

Index为字符串各个字符的编号,String为原串,Rank为对应Index为开头的后缀的排名,Pos为对应Index排名的后缀的位置(例如排名为1的后缀位置是6,故Pos(1)=6)。
对于任意两个Rank相邻的后缀ii+1,通过比较这两个后缀去掉首字符之后的后缀的rank可以确定ii+1这两个位置的字符是否可以相同,即比较Rank(Pos(i)+1)Rank(Pos(i+1)+1),如果Rank(Pos(i)+1)>Rank(Pos(i+1)+1)ii+1两位置字符不能相同且String(i)<String(i+1),否则,相同字符与其后缀相连,Rank(i)将会大于Rank(i+1),这改变了后缀的Rank,是不合法的;如果Rank(Pos(i)+1)<Rank(Pos(i+1)+1)String(i)String(i+1)
统计一遍有多少个Rank(Pos(i)+1)>Rank(Pos(i+1)+1)的位置,设其为m。如果m26则合法串个数为0(因为字符集大小为26)。
现在从Rank第一的串开始填字符,只有之前提到的那些位置是必须要比之前字符大的,其它都可以大于等于之前字符。而这不方便计算答案,现在将必须要增加的位置消去,设h=25m,则相当于字符集大小为h+1,每个Rank的字符都可以大于等于比它小的Rank的字符。那么这个的答案通过组合数学的隔板法得到为

Cnn+h

爆long long,需要高精度运算,可以使用python或java

代码

# by ztxN = 100005T = int(input())pos = [0 for i in range(N)]rank = [0 for i in range(N)]for iii in range(T):    n = int(input())    Str = input().split() # python2: raw_input()    for i in range(1,n+1):        pos[i] = int(Str[i-1])        rank[pos[i]] = i    if n == 1:        print("26")        continue    m = 0    rank[n+1] = 0    for i in range(2,n+1):        if rank[pos[i-1]+1] > rank[pos[i]+1]:            m = m+1    h = 25-m    if h < 0:        print("0")        continue    ans = 1    for i in range(n+1,n+h+1):        ans = ans * i    for i in range(1,h+1):        ans = ans // i    print(ans)
阅读全文
0 0
原创粉丝点击