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

    1511: [POI2006]OKR-Periods of Words

    https://www.lydsy.com/JudgeOnline/problem.php?id=1511

    题意:

      对于一个串的所有前缀,设为s,求出它的最大前缀Q,使得s为QQ的前缀。求最大前缀长度的和。

    分析:

      KMP+next数组。

      next数组表示的是这个字符串的最大的公共前缀后缀。对于字符串s,设其next为j,那么它的前j个和后j个是相等的。如果这j个没有重叠,那么所求的最长前缀就是1~n-j。把这个前缀重复两遍可以包含s。所求的就是最小的这样border,最小的j(j越小,相当于n个字符,后j个更少,那么剩余的所求的前缀就越长了)。然后求出最小的公共前后缀。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 inline int read() {
     6     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     7     for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     8 }
     9 
    10 const int N = 1000100;
    11 
    12 char A[N];
    13 int p[N];
    14 
    15 int main() {
    16     int n; cin >> n;
    17     scanf("%s",A+1);
    18     p[1] = 0;
    19     for (int i=2; i<=n; ++i) {
    20         int j = p[i-1];
    21         while (j && A[i]!=A[j+1]) j = p[j];
    22         if (A[i] == A[j+1]) j++;
    23         p[i] = j;
    24     }
    25     LL ans = 0;
    26     for (int i=1; i<=n; ++i) {
    27         int j = i;
    28         while (p[j]) j = p[j]; // 这里看到这样写的p[p[j]],其实每个p[i]在下面已经更新了,不需要跳很多次。 
    29         if (p[i] != 0) p[i] = j; // 类似于记忆化,前缀i的跳的最优位置。 
    30         ans += i - j; 
    31     }
    32     cout << ans;
    33     return 0;
    34 }
  • 相关阅读:
    python-----贴图 和 报错:OSError: image file is truncated (8 bytes not processed)的处理
    springboot集成RabbitMQ
    MySQL数据库设计规范
    腾讯云COS对象存储
    腾讯云OCR图片文字识别
    java基础之 java注释
    centos7下自动备份mysql数据库
    nginx配置ssl证书
    java基础之 控制语句
    js -- 操作sqlite数据库
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9350964.html
Copyright © 2011-2022 走看看