【HDU】5635 思维想法题

版权声明:抱最大的希望,为最大的努力,做最坏的打算。 https://blog.csdn.net/qq_37748451/article/details/86549110
Peter has a string s=s1s2...sn, let suffi=sisi+1...sn be the suffix start with i-th character of s. Peter knows the lcp (longest common prefix) of each two adjacent suffixes which denotes as ai=lcp(suffi,suffi+1)(1≤i<n). 

Given the lcp array, Peter wants to know how many strings containing lowercase English letters only will satisfy the lcp array. The answer may be too large, just print it modulo 109+7.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case: 

The first line contains an integer n (2≤n≤105) -- the length of the string. The second line contains n−1 integers: a1,a2,...,an−1 (0≤ai≤n). 

The sum of values of n in all test cases doesn't exceed 106.
Output
For each test case output one integer denoting the answer. The answer must be printed modulo 109+7. 
Sample Input
3
3
0 0
4
3 2 1
3
1 2
Sample Output
16250
26
0

题目大意:先输入一个t代表着测试组数,再输入一个n表示字符串的长度,s1,s2,s2,s2.......接下去输入n-1个数,表示的最长相同前缀的长度。

即:以第二组测试数据为例

 ai=lcp(suffi,suffi+1);

解题思路:

由于ai是相邻后缀的最长公共前缀LCP,那么我们手写几个样例对应的字符串看看是不是有什么规律,我们发现当a[i-1]!=0&&a[i] >= a[i-1]是不可能存在对应的字符串的如 1 2 0或 1 1 0,就算是递减的,也应该是依次减1的;同时a[i] <= n-i,即suff[i]与suff[i+1]的最长公共前缀应该小于n-i的,存在限制关系。还有就是出现0的个数就是应该结果乘以25的个数,如果所给数据是存在非0解的,那么结果最小解应该是26,所以初始化为26。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define PI acos(-1.0)
#define E 1e-6
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define maxn 1010
using namespace std;
#define ll long long int
int n;
int a[100005],s[100005];
int main()
{
  int t,tmp;
  cin>>t;
  while(t--)
  {
     cin>>n;
     memset(s,0,sizeof(s));
     for(int i=0;i<n-1;i++)
        cin>>a[i];
     s[n-1]=1;
     int ss=2;
     bool flag=0;
     for(int i=n-2;i>=0;i--)
     {
        if(a[i]!=0)
        {
           s[i]=s[i+1];
           if(s[i]==s[i+a[i]+1])
           {
                flag=1;
                break;
           }
           for(int j=1;j<=a[i];j++)
           {
                if(s[i]!=s[i+j])
                {
                  flag=1;
                  break;
                }
           }
        }
        else
                s[i]=ss++;
        if(flag!=0)
                break;
     }
     ll ans=26;
     tmp=s[n-1];
     for(int i=n-2;i>=0;i--)
     {
        if(s[i]!=tmp)
        {
         ans*=25;
         tmp=s[i];
         ans%=MOD;
        }
     }
     if(flag!=0)
        cout<<"0"<<endl;
     else
        cout<<ans<<endl;
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37748451/article/details/86549110