zoukankan      html  css  js  c++  java
  • 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] = '';
            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
    ", 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;
    }
    一步一步,永不停息
  • 相关阅读:
    Translation Rule 和命中法则
    Cisco Extension Mobility配置步骤详解
    tclsh命令, cisco 快速测试工具
    136、多继承的优缺点,作为一个开发者怎么看待多继承
    135、 虚函数的内存结构,那菱形继承的虚函数内存结构呢
    134、隐式转换,如何消除隐式转换?
    133、说一下你理解的 ifdef endif代表着什么?
    132、 静态成员与普通成员的区别是什么?
    131、全局变量和static变量的区别
    130、定义和声明的区别
  • 原文地址:https://www.cnblogs.com/Willems/p/12546892.html
Copyright © 2011-2022 走看看