zoukankan      html  css  js  c++  java
  • [国家集训队]最长双回文串

    题意是 求字符串 A +B = C 且 C 在序列中 A 和 B 都是回文串

    运用了回文字符串优美的性质:删掉任意两个相同的字符仍然回文且长度减2

    看到这题之后 我在想 如果把 A 字符串的末尾 设为 A 的长度 B 字符串的开始 设为 B 的长度

    然后 设 A 字符串的 右端点 代表的长度为 (R_i)
    设 B 字符串的 左端点 代表的长度为 (L_i)
    然后 求 (max)({L_i + R_i})
    但是你会发现这样是不会得到最优解的 就像这样

    aaaaa
    

    答案是5 但是你只更新了 (L_5)(R_1) 的值 所以程序认为的答案不是5 是 0

    这样你就要开始递推

    其实你统计的信息都是在分隔符上…然后你会发现两个分隔符里有一个字符

    所以你 递推式 是 (L_i) =max{ (L_i) , (L_{i+2} - 2)} (R_i) = max{(R_i) , (R_{i-2}-2)}

    然后再取 (max)({L_i+R_i})

    #include<bits/stdc++.h>
    using namespace std ;
    #define int long long
    #define fi first
    #define se second
    #define pb emplace_back
    inline int read() {
    	register char c = getchar() ;
    	register int x = 0 , f = 1 ;
    	for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ;
    	for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ;
    	return x * f ;
    }
    template < typename T > inline bool cmax(T & x , T y) {
    	return x < y ? x = y , 1 : 0 ;
    }
    template < typename T > inline bool cmin(T & x , T y) {
    	return x > y ? x = y , 1 : 0 ;
    }
    inline int QP(int x , int y , int Mod) { int ans = 1 ;
    	for( ; y ; y >>= 1 , x = (x * x) % Mod)
    		if(y & 1) ans = (ans * x) % Mod ;
    	return ans ;
    }
    const int N = 2e5 + 10 ;
    char s[N] , fix[N << 1] ;
    int p[N << 1] ;
    int L[N << 1] , R[N << 1] ;
    signed main() {
    	scanf("%s" , s + 1) ;
      int n = strlen(s + 1) ;
      int len = 0 ;
      fix[++ len] = '$' ;
      fix[++ len] = '%' ;
      for(register int i = 1 ; i <= n ; i ++)
        fix[++ len] = s[i] , fix[++ len] = '%' ;
      int mid = 0 , id = 0 ;
      for(register int i = 1 ; i <= len ; i ++) {
        if(i <= id) p[i] = min(p[(mid << 1) - i] , id - i + 1) ;
        while(fix[i - p[i]] == fix[i + p[i]]) p[i] ++ ;
        if(i + p[i] > id) mid = i , id = i + p[i] - 1 ;
        cmax(L[i + p[i] - 1] , p[i] - 1) ;
        cmax(R[i - p[i] + 1] , p[i] - 1) ;
      } int ans = 0 ;
      for(register int i = 2 ; i <= len ; i += 2) cmax(R[i] , R[i - 2] - 2) ;
      for(register int i = len ; i >= 1 ; i -= 2) cmax(L[i] , L[i + 2] - 2) ; 
      int QWQ = 2333 ;
      for(register int i = 1 ; i <= len ; i ++) (L[i] && R[i]) ? cmax(ans , L[i] + R[i]) : QWQ;
      printf("%lld
    " , ans) ;
    	return 0 ;
    }
    
  • 相关阅读:
    如何用cmd命令加密文件夹
    C++异常处理
    STRTOK
    如何生成Detours.lib——Detours的使用准备
    学习C++心得与值得一看的书
    工作两年后的感悟
    MFC十八个简单问题转载
    程序员的五种非技术错误 转载
    用VC写DLL中"error LNK2005: _DllMain@12 already defined"的错误
    CxImage
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/11646391.html
Copyright © 2011-2022 走看看