zoukankan      html  css  js  c++  java
  • [SHOI2011]双倍回文

    首先我们发现一个双倍回文串当且仅当本身是一个回文串且左右两边都是回文串。

    那么对于右边的回文串,到中心 (i) 时,Manacher 所记录的 maxr 一定大于 (i),如果满足这个条件,那就判断 (i)(i) 关于 mid 的对称串是否有交点,有交点就说明这是双倍回文串。

    时间复杂度 (O(n))

    #include <bits/stdc++.h>
    #define reg register
    #define ll long long
    #define ull unsigned long long
    #define rep(i,a,n) for(reg int (i)=(a);(i)<=(n);++(i))
    #define per(i,a,n) for(reg int (i)=(a);(i)>=(n);(i)--)
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define SZ(x) ((int) (x).size())
    #define debug(typ...) fprintf(stderr, typ)
    using namespace std;
    const int iINF=numeric_limits<int>::max();
    const ll lINF=numeric_limits<ll>::max();
    int fastin() {
      reg int x = 0, ch = getchar(), f = 0;
      while(!isdigit(ch)) (ch == '-') && (f = 1), ch = getchar();
      while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
      return f ? -x : x;
    }
    const int MAXN=5e5+10;
    const int MAXM=1e6+10;
    int n,f[MAXM];
    char s[MAXN],ss[MAXM];
    void work() {
      n=fastin(),scanf("%s",s+1);
      rep(i,1,n) ss[(i<<1)-1]='#',ss[i<<1]=s[i];
      n=(n<<1)+1,ss[n]='#';
      int r=0,mid=0,ans=0;
      for(reg int i=1;i<=n;i+=2) {
        if(i<r) f[i]=min(f[(mid<<1)-i],r-i);
        else f[i]=1;
        if(i<r&&i-f[i]<mid) ans=max(ans,(i-mid)<<1);
        while(i-f[i]>=1&&i+f[i]<=n&&ss[i-f[i]]==ss[i+f[i]]) ++f[i];
        if(i+f[i]>r) r=i+f[i],mid=i;
      }
      printf("%d
    ",ans);
    }
    signed main() {
      int _=1;
      // _=fastin();
      while(_--) work();
      return 0;
    }
    
  • 相关阅读:
    RN的win7开发环境部署和问题解决
    Android EditText弹出软键盘实现页面标题头不动,软键盘弹出在编辑框下面
    android打包生成apk时自定义文件名版本号。自定义项目字段等等
    Android ConstraintLayout 约束布局属性
    AS基本设置
    PermissionUtils
    kotlin之字符串模板
    kotlin之字符串
    kotlin之数组
    kotlin之布尔类型
  • 原文地址:https://www.cnblogs.com/Lonely-233/p/13893962.html
Copyright © 2011-2022 走看看