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
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define INF 0x3fffffffffffffff
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
int n;
int val[maxn];
void solve()
{
int i, j, k, st, flag = 1;
scanf("%d", &n);
for (i = 1; i <= n - 1;i++)
{
scanf("%d", &val[i]);
if (val[i] > n - i)
{
flag = 0;
}
}
if (flag == 0)
{
puts("0");
return;
}
ll res = 26;
ll num = 0;
if (val[1])
{
flag = 1;
}
else
{
flag = 0;
num = 1;
}
for (i = 2; i <= n - 1; i++)
{
if (flag == 0)
{
if (val[i] == 0)
{
num++;
flag = 0;
}
else
{
flag = 1;
}
}
else
{
if (val[i] != val[i - 1] - 1)
{
puts("0");
return;
}
if (val[i] == 0)
{
num++;
flag = 0;
}
}
}
for (i = 1; i <= num; i++)
{
res = res * 25;
res %= mod;
}
printf("%lld\n", res);
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
solve();
}
//system("pause");
return 0;
}