HDU5635 LCP Array BestCoder

说实话 这道题我是不会写 这种思维题目 我觉得bc的时候即使自己慢慢想 也不一定能全想对

这道题求后缀的最长前缀
其实要注意这几个地方

第一 数列如果前一位不是0 那么你这一位就只能比前一位少1

HDU5635 LCP Array BestCoder_第1张图片
我画的图好丑啊
大家可以观察数列 如果a[i]不为0 假设a[i]==3,那么就是图上这种情况
a[i]–a[i+3]是和a[i+1]–a[i+4]是相等的,这是题目的意思,我们还可以推出其实a[i]==a[i+1]==a[i+2]==a[i+3]==a[i+4]…………..我们称这个为(1)式
其实图上就可以发现了
那么a[i+1]就只能等于2,为什么?
为什么不能等于别的数?
假设你等于3,就是说a[i+1]–a[i+4]和a[i+2]–a[i+5]是一样的,那么
就是说i+1到i+5都是一样的,那么根据(1)式,a[i]就应该等于4,现在你a[i]==3,而你a[i+1]==3,这就是自相矛盾了

第二 数列当前的值所代表的前缀不能大于n-i

这个很好理解,你的字符串只有n位,怎么得出从你这一位开始相同的字符串长度最后的位置超过n
就是样例中的,理解一下
3
1 2
这一组数据,你的字符串长度只有3,然后你的a[2]==2,也就是说你的字符串的2位置和3位置开始的字符串相同的前缀超过了3,怎么可能?

然后,这两种情况之排序没有答案后,就可以计算了,遇到0就乘以25就可以了,不乘26?
你只需要和上一位不一样就行了,0代表的是没有前缀。

#include <cstdio>

typedef long long ll;
const ll MOD=1e9 +7;
const int maxn=1e5 +5;
int a[maxn];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        ll sum=26;
        for(int i=1; i<n; i++){
            scanf("%d",&a[i]);
        }
        for(int i=1; i<n; i++){
            if(a[i]>n-i||a[i-1]!=0&&a[i]!=a[i-1]-1){
                sum=0;
                break;
            }
            if(a[i]==0){
                sum*=25;
                if(sum>=MOD)sum%=MOD;
            }
        }
        printf("%lld\n",sum%MOD);
    }
    return 0;
}

你可能感兴趣的:(HDU5635 LCP Array BestCoder)