HDU5635 LCP Array BestCoder

来源:互联网 发布:js调用微信分享sdk 编辑:程序博客网 时间:2024/05/22 08:12

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

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

第一 数列如果前一位不是0 那么你这一位就只能比前一位少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;}
1 0
原创粉丝点击