LCP Array
Accepts: 131
Submissions: 1352
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
Peter有一个字符串s=s1s2...sn, 令suffi=sisi+1...sn是s第i字符开头的后缀. Peter知道任意两个相邻的后缀的最长公共前缀ai=lcp(suffi,suffi+1)(1≤i<n). 现在给你数组a, Peter有多少个仅包含小写字母的字符串满足这个数组. 答案也许会很大, 你只要输出对109+7取模的结果即可.
输入描述
输入包含多组数据. 第一行有一个整数T, 表示测试数据的组数. 对于每组数据: 第一行包含一个整数n (2≤n≤105)表示字符串的长度. 第二行包含n−1个整数: a1,a2,...,an−1 (0≤ai≤n). 所有数据中n的和不超过106.
输出描述
对于每组数据, 输出答案对109+7取模的结果.
输入样例
3 3 0 0 4 3 2 1 3 1 2
输出样例
16250 26 0
这道题的题意不是特别好理解,其实就是说有一个长字符串,然后告诉你每两个相邻字母开始的字符串,从第一个开始连续的有多少个字符是相同的,输入的数肯定不能大于从其开始的字符串的总长度,然后很必要的输入的数必定是严格递减的,一个一个的递减,最后算出这个字符串有多少种可能性。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define mm 1000000007
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
long long int ans=26;
int x[100010];
memset(x,0,sizeof(x));
scanf("%d",&n);
for(int i=1;i<n;i++)
scanf("%d",&x[i]);
for(int i=n-1;i>0;i--)
{
if(x[i]+1!=x[i-1]&&x[i-1])
{
ans=0;
break;
}
if(x[i]+i>n)
{
ans=0;
break;
}
if(!x[i])
ans*=25,ans%=mm;
}
printf("%I64d\n",ans%mm);
}
return 0;
}