杭电acm3336

http://acm.hdu.edu.cn/showproblem.php?pid=3336

这题运用了next函数的性质,next[n],其实就是求从前往后数的字符串和从后往前数的字符串完全对应的最长位数(从后数和从前数不能完全相同,即去掉其本身);

将出现次数相同的next依次累加,最后汇总(记得加上每一个子串都有本身出现了的一次),这里使用的next函数是以next[0]=-1开始的

苦逼……next[0]=0的写法还没研究出来

View Code
#include<stdio.h>
#include<string.h>
#define mod 10007
int next[200010],sum[200010];
char s[200010];
void pre(int n)
{
     int i,j=-1;
     next[0]=-1;
     i=0;
     while(s[i])
     {
          if(j==-1||s[i]==s[j])
          {
              i++;
              j++;
              next[i]=j;
          }
          else j=next[j];
     }
}
int main()
{
    int t,n,i,ss;
    char c[10];
    scanf("%d",&t);
    while(t--)
    {
       ss=0;
       scanf("%d",&n);
       gets(c);
       scanf("%s",s);
       pre(n);
       for(i=0;i<200001;i++)
          sum[i]=0;
       for(i=1;i<=n;i++)
          sum[next[i]]=(sum[next[i]]+1)%mod;
       for(i=1;i<=n;i++)
            ss=(ss+sum[i]+1)%mod;
       printf("%d\n",ss);
    }
    return 0;
}

 

#include<stdio.h>
#include<string.h>
#define mod 10007
int next[200010],sum[200010];
char s[200010];
void pre(int n)
{
     int i,j=-1;
     next[0]=-1;
     i=0;
     while(s[i])
     {
          if(j==-1||s[i]==s[j])
          {
              i++;
              j++;
              next[i]=j;
          }
          else j=next[j];
     }
}
int main()
{
    int t,n,i,ss;
    char c[10];
    scanf("%d",&t);
    while(t--)
    {
       ss=0;
       scanf("%d",&n);
       gets(c);
       scanf("%s",s);
       pre(n);
       for(i=0;i<200001;i++)
          sum[i]=0;
       for(i=1;i<n;i++)
          sum[next[i]]=(sum[next[i]]+1)%mod;
       for(i=1;i<n;i++)
            ss=(ss+sum[i]+1)%mod;
       printf("%d\n",ss);
    }
    return 0;
}

 

posted @ 2013-05-09 23:36  执着追求的IT小小鸟  阅读(143)  评论(0)    收藏  举报