zoukankan      html  css  js  c++  java
  • CF961F k-substring

    题意:给你一个字符串(sl<=1e6),问每一个起点到1和终点到sl距离相等的子串的最长不等于串长的border。

    标程:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 const int can=31;
     7 const int mod=20030321;
     8 const int N=1000005;
     9 int ha[N],pow[N],n,ans[N],l,r,len,cnt;
    10 char s[N];
    11 int S(int x,int l)
    12 {return ((ll)ha[x+l-1]-(ll)ha[x-1]*pow[l]%mod+mod)%mod;}
    13 int main()
    14 {
    15     scanf("%d%s",&n,s+1);
    16    pow[0]=1;
    17    for (int i=1;i<=n;i++) pow[i]=(ll)pow[i-1]*can%mod;
    18    for (int i=1;i<=n;i++) ha[i]=((ll)ha[i-1]*can%mod+(s[i]-'a'+1))%mod;
    19    if (n&1) l=r=n/2+1;else l=n/2,r=l+1;len=1;
    20    while (r<=n)
    21    {
    22        while (len!=-1&&S(l,len)!=S(r-len+1,len)||len>=r-l+1) len-=2;
    23       ans[++cnt]=len;
    24        l--,r++;    len+=2;
    25     }
    26     for (int i=cnt;i>=1;i--) printf("%d ",ans[i]);
    27    return 0;
    28 }

    题解:hash+单调性

    对于每一个串二分+hash?这样的答案并没有单调性。

    但是(分析数据)经过有理有据的推导,发现所有这样的串的答案是具有单调性的。

    对于一个串,如果在它的两边各加一个字符,那么它的border长度最多+2。

    证明:

    比如现在完成一个串A....B(A,B都是字符块,并且为该串的最长border

    左右各扩展:xA....By

    可以证明最优情况下的匹配是xAz...gBy,不会出现xAC...DBy(C,D是长度>1的字符块)

    如果存在xAC=DBy.那么提取C的最后一个字母=y,D的第一个字母=x,即xACy=xDBy。

    所以AC=DB,不满足A,B是最长border。

    然后就直接hash比较即可。

    时间复杂度O(n)。

  • 相关阅读:
    第6章 键盘_6.5 插入符号(不是光标)
    第6章 键盘_6.3-6.4 字符消息、键盘消息和字符集
    第6章 键盘_6.1-6.2 键盘基础与击键消息
    第5章 绘图基础_5.6 矩形、区域和剪裁
    第4章 进程(1)
    第3章 内核对象(2)
    第3章 内核对象(1)
    第2章 字符和字符串处理(2)
    第2章 字符和字符串处理(1)
    第1章 错误处理
  • 原文地址:https://www.cnblogs.com/Scx117/p/8727909.html
Copyright © 2011-2022 走看看