Codeforces Global Round 7 D2. Prefix-Suffix Palindrome (Hard version)

Link
题意:
\(a\) 是 \(s\) 的前缀,\(b\) 是 \(s\) 的后缀
使 \(a+b\) 是可以找到的最大的回文串
\(a\) 或 \(b\) 可以是空串
思路:
找出最大长度 \(k\) 使 \(s[0,k-1]+s[len(s)-k,len(s)-1]\) 是回文串
再用 Manacher 算法求出 \(s[k,len(s)-k-1]\) 中以 \(s[k]\) 为右端的的最大回文串和以 \(s[len(s)-k-1]\)为左端的最大回文串(计算出 \(len[i]\) 后,判断以 \(i\) 为中心的最大回文串的左端和右端即可)
把较大的那个回文串加在开始找到的长度为 \(2*k\) 的回文串中间即是最大答案
注意:当一开始找长度 \(k\) 时 \(k-1\ge len(s)-k\) 时,\(s\) 本身就是一个回文串
代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1e6+5;

char s[N];
char str[N*2];
int len[N*2];

pair<int,int> Manacher(int l,int r) {
    str[0]='$';
    int k=0;
    for(int i=l;i<=r;i++) str[++k]='#',str[++k]=s[i];
    str[++k]='#';
    len[0]=0;
    int id=0,mx=0;
    int mxl=0,mxr=0;
    for(int i=1;i<=k;i++) {
        len[i]=i<mx?min(mx-i,len[2*id-i]):1;
        while(i-len[i]>=0&&i+len[i]<=k&&str[i-len[i]]==str[i+len[i]]) ++len[i];
        if(len[i]+i>mx)mx=len[i]+i,id=i;
        if(len[i]==i) {
            if(len[i]-1>mxl) mxl=len[i]-1;
        }
        else if(len[i]==k-i+1) {
            if(len[i]-1>mxr) mxr=len[i]-1;
        }
    }
    if(mxl>mxr) return make_pair(0,mxl);
    else return make_pair(1,mxr);
}
int main() {
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;cin>>T;
    while(T--) {
        cin>>s;
        int l=0,r=strlen(s)-1;
        while(l<r&&s[l]==s[r]) l++,r--;
        if(l>=r){cout<<s<<endl;continue;}
        pair<int,int> res=Manacher(l,r);
        for(int i=0;i<l;i++) cout<<s[i];
        if(res.first==0) for(int i=l;i<=l+res.second-1;i++) cout<<s[i];
        else if(res.first==1) for(int i=r-res.second+1;i<=r;i++) cout<<s[i];
        for(int i=l-1;i>=0;i--) cout<<s[i];
        cout<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/c4Lnn/p/12534074.html

时间: 2024-08-29 14:56:35

Codeforces Global Round 7 D2. Prefix-Suffix Palindrome (Hard version)的相关文章

Codeforces Global Round 7 D2. Prefix-Suffix Palindrome (Hard version) -- manacher

D2. Prefix-Suffix Palindrome (Hard version) 题目链接 manacher做法 #include <bits/stdc++.h> using namespace std; const int N = 1e6 + 10; int p[N*2]; string manacher(string ss) { int len = ss.size(); string s; s.resize(len*2+2); for(int i=len;i>=0;i--) {

Codeforces Global Round 1 (A-E题解)

Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^(k-1)+a2*b^(k-2)+...+ak*b^0的奇偶性. 题解: 暴力求模2意义下的值就好了. 代码如下: #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5+5; int

【手抖康复训练1 】Codeforces Global Round 6

[手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思路手抖过不了样例,C题秒出思路手抖过不了样例*3 D题 手抖 过的了样例 ,调了1h,赛后发现变量名写错了,改一个字符就能AC... 题目等补完题一起放上来QAQ 原文地址:https://www.cnblogs.com/ttttttttrx/p/12110199.html

Codeforces Global Round 7

传送门 A. Bad Ugly Numbers 233333. Code /* * Author: heyuhhh * Created Time: 2020/3/19 22:36:37 */ #include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath> #include <set> #include <

Codeforces Global Round 7【ABCD】(题解)

目录 涵盖知识点:思维.构造.马拉车. 比赛链接:传送门 D题只有数据范围的区别,故只写D2. 好多题啊,随缘更新.(其实懒得写) A - Bad Ugly Numbers B - Maximums C - Permutation Partitions D2 - Prefix-Suffix Palindrome (Hard version) 涵盖知识点:思维.构造.马拉车. 比赛链接:传送门 D题只有数据范围的区别,故只写D2. 好多题啊,随缘更新.(其实懒得写) A - Bad Ugly Nu

【Codeforces Global Round 1 E】Magic Stones

[链接] 我是链接,点我呀:) [题意] 你可以把c[i]改成c[i+1]+c[i-1]-c[i] (2<=i<=n-1) 问你能不能把每一个c[i]都换成对应的t[i]; [题解] d[i] = c[i+1]-c[i]; (1<=i<=n-1) change c[i] c[i]' = c[i+1]+c[i-1]-c[i]; d[i-1] = c[i]'-c[i-1]; = c[i+1]+c[i-1]-c[i]-c[i-1] == c[i+1]-c[i] = d[i]; d[i]

Frets On Fire --- 2019 Codeforces Global Round 2 Problem D

原题:https://codeforces.com/contest/1119/problem/D 题意大概是一个n行1e18列的矩阵,其中每行第一个数为s[i],剩下的数每行依次以1的速度递增.就是说,矩阵元素 a[i][j] = s[i] + j .有q个询问,每个询问有两个参数l,r,求矩阵第l列到第r列(所有行)一共出现了几个不同的数. 这道题首先要先想到,两个参数 [l,r] 其实等价于一个参数 [0,r-l] ,也就是说矩阵第0~r-l行出现的数字的个数其实和第l-r行出现的个数是一样

[Codeforces]Codeforces Global Round 1

A - Parity 题意 给定一个$b$进制数,要求输出它在十进制下是奇数还是偶数. 分析 花了我略多的时间,首先题目中给的数字范围很大,不能直接转化为10进制. 分析性质,发现只有奇数乘奇数还是奇数,其他都是偶数. 对奇数进制和偶数进制分类讨论. 偶数进制看最低位的奇偶性,如果是奇数那么这个数就是奇数,不然是偶数. 奇数进制看每一位上奇数的个数,如果是奇数个奇数就是奇数,不然是偶数. 代码 1 #include <bits/stdc++.h> 2 using namespace std;

【 Codeforces Global Round 1 B】Tape

[链接] 我是链接,点我呀:) [题意] x轴上有m个连续的点,从1标号到m. 其中有n个点是特殊点. 让你用k段区间将这n个点覆盖. 要求区间的总长度最小. [题解] 一开始假设我们需要n个胶带(即包含每一个点) 然后因为k<=n 所以可能胶带不够用. 那么就得一个胶带跨过两个点. 怎么选择最好呢? 可以把b[i]-b[i-1]-1处理出来排个序. (优先取较小的花费) 然后取前n-k个累加和sum. 因为每取一个就少用一段胶带. 然后sum+n就是答案了 [代码] import java.i