zoukankan      html  css  js  c++  java
  • Bzoj 3620---似乎在梦中见过的样子(KMP)

    题目背景第二行madoka打错了???

    KMP暴力啦~~~~

    我们使用 KMP 的 P 数组来找这个前缀,直接从 P[r] 向前找最坏情况会导致变成 O(n^3) ,所以我们应该优化一下:

    P 数组如果视为 Father 数组,那么它是一棵树。我们求的就是一个节点到根的路径上有没有区间 [k, (r-l+1)/2) 的数。

    我们求 P 的时候是从根向叶子求的,所以我们可以同时维护根到某个节点 j 的所有数中,大于等于 k 的数中最小的一个。

    然后我们对于每一个右端点,只要判断这个点到根的路径中大于等于 k 的数中最小的一个是否小于 (r - l + 1) / 2 就可以了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<algorithm>
     7 using namespace std;
     8 const int INF=999999999;
     9 int ans=0,p[1500005],num[1500005],n,k;
    10 char st[1500005];
    11 int main()
    12 {
    13     gets(st+1);
    14     scanf("%d",&k);
    15     int n=strlen(st+1);
    16     for (int i=1; i<=n; i++){
    17         int j=0;
    18         p[1]=0; num[0]=INF;
    19         for (int t=2; t<=n-i+1; t++){
    20             while (j>0 && st[i+j]!=st[t+i-1]) j=p[j];
    21             if (st[i+j]==st[i+t-1]) j++;
    22             p[t]=j;
    23             if (j<k) num[j]=INF; else num[j]=min(j,num[p[j]]);
    24             if ((num[j]<<1)<t) ans++;
    25         }        
    26     }
    27     printf("%d
    ",ans);
    28     return 0;
    29 }

    miao~~~

  • 相关阅读:
    C++迭代器
    JdbcTemplateUtil 工具类分享
    PE和CDlinux二合一启动盘制作
    程序员自述——2019新年篇
    HTML/CSS常用单词
    JAVA学习常用单词
    Spring集成Mybatis3
    Spring集成struts2
    解决VS2010打开Web页面时经常由于内存较低而导致VS2010自动关闭的问题
    年终总结
  • 原文地址:https://www.cnblogs.com/wangyh1008/p/9397121.html
Copyright © 2011-2022 走看看