您的位置:首页 > 其它

HDU5635 LCP Array BestCoder

2016-03-07 11:05 232 查看
说实话 这道题我是不会写 这种思维题目 我觉得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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: