zoukankan      html  css  js  c++  java
  • [POI2006]OKR-Periods of Words

    题目描述

    一个串是有限个小写字符的序列,特别的,一个空序列也可以是一个串. 一个串P是串A的前缀, 当且仅当存在串B, 使得 A = PB. 如果 P A 并且 P 不是一个空串,那么我们说 P 是A的一个proper前缀. 定义Q 是A的周期, 当且仅当Q是A的一个proper 前缀并且A是QQ的前缀(不一定要是proper前缀). 比如串 abab 和 ababab 都是串abababa的周期. 串A的最大周期就是它最长的一个周期或者是一个空串(当A没有周期的时候), 比如说, ababab的最大周期是abab. 串abc的最大周期是空串. 给出一个串,求出它所有前缀的最大周期长度之和.。

    输入输出样例

    输入样例#1:
    8
    babababa
    输出样例#1:
    24
    最长循环串长度=总长度-最短相同前后缀长度(也就是kmp中的next)
    但我们的kmp求的是最长
    相同前后缀长度
    举个例子:

      abababa next[7]=5,所以abababa可以由两个ababa组成

      同理ababa可以由aba组成

      aba可以由a组成

      a的next=0,所以结束

      因此,a一定既是abababa的前缀,又是它的后缀,并且是最小的

    这样每次我们都用上法处理O(n^2)
    可以利用前面更新的next,用O(1)的时间更新next
    方法:
    如果next[next[i]]!=0则next[i]=next[next[i]]
    因为按此方法,前面得到的肯定是最短的next,此刻对于next[next[i]]已经是最优,
    不需要再往前找了
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 char s[1000001];
     8 int k,nxt[1000001];
     9 long long ans;
    10 int main()
    11 {char ch;
    12 int i,j;
    13     cin>>k;
    14     ch=getchar();
    15      for (i=1;i<=k;i++)
    16      {
    17         scanf("%c",&s[i]);
    18      }
    19      nxt[1]=0;j=0;
    20       for (i=2;i<=k;i++)
    21       {
    22          while (j&&s[j+1]!=s[i]) j=nxt[j];
    23          if (s[j+1]==s[i]) j++;
    24          nxt[i]=j;
    25       }
    26       for (i=1;i<=k;i++)
    27       if (nxt[nxt[i]]) 
    28       nxt[i]=nxt[nxt[i]];
    29     for (i=1;i<=k;i++)
    30     if (nxt[i]) ans+=i-nxt[i];
    31 cout<<ans;
    32 }
  • 相关阅读:
    已解决: 已引发: "无法加载 DLL“opencv_core2410”: 找不到指定的模块。
    Xcode 设置图片全屏显示
    独创轻松实现拖拽,改变层布局
    WCF Odata 开放数据协议应用
    MVC中,加入的一个aspx页面用到AspNetPager控件处理办法
    关于 HRESULT:0x80070
    Springboot文件上传大小设置
    Jquery Validate 表单验证使用
    Quartz任务调度框架使用
    js中常见命令
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7367670.html
Copyright © 2011-2022 走看看