记录编号 357015 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOI 2016]优秀的拆分 最终得分 100
用户昵称 Gravatar再见 是否通过 通过
代码语言 C++ 运行时间 0.458 s
提交时间 2016-12-08 13:03:43 内存使用 1.95 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<cctype>
  5.  
  6. typedef unsigned long long int ULL;
  7.  
  8. const int prime[]={59,3,41,43,47,71,5,7,11,13,61,19,23,29,31,37,73,53,2,17,67,79,83,89,97,101};
  9.  
  10. int read(char *s){
  11. char *p=s,ch;
  12. while(ch=getchar(),!isalpha(ch)) if(ch==EOF) return 0;
  13. while((*(++p))=ch,ch=getchar(),isalpha(ch));
  14. return p-s;
  15. }
  16. #define HASH(i,l) (hash[i]-hash[i+l]*xpow[l])
  17. #define HASH2(i,l) (hash2[i+l-1]-hash2[i-1]*xpow[l])
  18.  
  19. struct suf{
  20. ULL hash[30010],x,xpow[30010],hash2[30010];
  21. int n; char str[30010];
  22. void init(ULL _x){
  23. xpow[0]=1; x=_x;
  24. for(int i=1;i<=30000;xpow[i]=xpow[i-1]*x,i++);
  25. }
  26. void reset(){
  27. n=strlen(str+1); hash[n+1]=0;
  28. for(int i=n;i>=1;i--) hash[i]=hash[i+1]*x+prime[str[i]-'a'];
  29. //for(int i=1;i<=n;i++) hash2[i]=hash2[i-1]*x+prime[str[i]-'a'];
  30. }
  31. int erfen(int x,int y,int limit){
  32. int l=0,r=limit,ans=0,mid;
  33. while(l<=r){
  34. mid=(l+r)>>1;
  35. if(HASH(x,mid)==HASH(y,mid)/*&&HASH2(x,mid)==HASH2(y,mid)*/) ans=mid,l=mid+1;
  36. else r=mid-1;
  37. }
  38. return ans;
  39. }
  40. }s1,s2;
  41.  
  42. long long ans;
  43. int len,f[30010],g[30010];
  44.  
  45. int main()
  46. {
  47. //freopen("a.txt","r",stdin);
  48. freopen("excellent.in","r",stdin);
  49. freopen("excellent.out","w",stdout);
  50. s1.init(29); s2.init(4157);
  51. while(len=read(s1.str),len){
  52. s1.str[len+1]=s2.str[len+1]='\0';
  53. for(int i=1;i<=len;i++) s2.str[len-i+1]=s1.str[i];
  54. memset(f,0,sizeof(f)); memset(g,0,sizeof(g));
  55. s1.reset(); s2.reset();
  56. for(int i=1;i<=len;i++)
  57. for(int l=i;l+i<=len;l+=i){
  58. int q=s2.erfen(len-l-i+1,len-l+1,i),p=s1.erfen(l,l+i,i);
  59. if(i-p-q<0){
  60. f[l-q+1]++;f[l+p-i+1]--;
  61. g[l+i+i-q]++;g[l+i+p]--;
  62. }
  63. }
  64. ans=0;
  65. for(int i=1;i<=len;i++) f[i]+=f[i-1],g[i]+=g[i-1],ans+=f[i]*g[i-1];
  66. printf("%lld\n",ans);
  67. }
  68. return 0;
  69. }
  70.