D. Prefix-Suffix Palindrome (马拉车)

题目:传送门

题意:给你字符串 s ,问长度最大的字符串 t = a + b 是什么,其中,t 是回文串, a 是字符串 s 的前缀, b 是字符串 s 的后缀。

 

思路:

我们先把能构成回文的,前缀和后缀取出来,然后对剩下的字符串,求,最长的前缀回文,最长后缀回文,取两者最大即可。

 

#include <bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
#define fir first
#define sec second
using namespace std;

const int N = 1e6 + 5;

const LL mod = 1e9 + 7;

LL ksm(LL a, LL b) { LL ans = 1LL; while(b) { if(b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; }  return ans; }

struct manacher {
    char ch[N << 1];
    int p[N << 1];

    void work(char *s, int len) {
        int l = 0;
        ch[l++] = '&'; ch[l++] = '#';
        rep(i, 0, len - 1) {
            ch[l++] = s[i];
            ch[l++] = '#';
        }
        ch[l] = '\0';
        int mx = 0, id = 0;
        rep(i, 0, l - 1) {
            p[i] = i < mx ? min(p[2 * id - i], mx - i) : 1;
            while(ch[i + p[i]] == ch[i - p[i]]) p[i]++;
            if(i + p[i] > mx) mx = i + p[i], id = i;
        }
    }
    bool judge(int l, int r) {
        int mid = (l * 2 + r * 2) >> 1;
        return p[mid] - 1 >= r - l + 1;
    }
}Man;

char a[N], b[N];

void solve() {

    int n;
    scanf("%s", a + 1);
    n = strlen(a + 1);
    int L = 1, R = n;

    while(L < R) {
        if(a[L] == a[R]) L++, R--;
        else break;
    }

    if(L >= R) {
        printf("%s\n", a + 1);
        return ;
    }

    int cnt = 0;
    rep(i, L, R) b[cnt++] = a[i];
    Man.work(b, cnt);
    int res = 0;
    pair < int, int > tmp;
    rep(i, 0, cnt - 1) {
        if(Man.judge(1, i + 1)) {
            if(i + 1 > res) {
                res = i + 1;
                tmp = make(0, i);
            }
        }
        if(Man.judge(i + 1, cnt)) {
            if(cnt - i > res) {
                res = cnt - i;
                tmp = make(i, cnt - 1);
            }
        }
    }

    rep(i, 1, L - 1) printf("%c", a[i]);
    rep(i, tmp.first, tmp.sec) printf("%c", b[i]);
    rep(i, R + 1, n) printf("%c", a[i]);
    puts("");

}


int main() {
    int _; scanf("%d", &_);
    while(_--) solve();


//    solve();

    return 0;
}

 

posted on 2020-03-22 16:52  Willems  阅读(171)  评论(0编辑  收藏  举报

导航