abc284F 字首+逆序+字尾

chenfy27發表於2024-03-08

題面:給一個長度為2n的字串T,問是否存在長度為n的字串S,滿足:T = S的字首 + 整串S逆序 + S的字尾。
範圍:n<=1e6

思路:字串雜湊,列舉S的起點逐一判斷,如果前i個字元加後n-i個字元組成的長為n的字串,正好和中間串的逆序相同,則為解。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)

using hval = tuple<int,int,int>;
struct Hasher {
    const int B1 = 131, M1 = 1000000123;
    const int B2 = 137, M2 = 1000000223;
    const int B3 = 139, M3 = 1000000007;
    vector<int> P1, P2, P3, L1, L2, L3;
    template<typename InputIt>
    void init(InputIt st, InputIt ed) {
        int n = distance(st, ed);
        P1 = P2 = P3 = vector<int>(n+5, 1);
        rep(i,1,n) {
            P1[i] = P1[i-1] * B1 % M1;
            P2[i] = P2[i-1] * B2 % M2;
            P3[i] = P3[i-1] * B3 % M3;
        }
        L1 = L2 = L3 = vector<int>(n+5, 0);
        rep(i,1,n) {
            L1[i] = (L1[i-1] * B1 + st[i-1]) % M1;
            L2[i] = (L2[i-1] * B2 + st[i-1]) % M2;
            L3[i] = (L3[i-1] * B3 + st[i-1]) % M3;
        }
    }
    hval get(initializer_list<int> arg) { // [l1,r1),[l2,r2)..., 0-based
        assert(arg.size() % 2 == 0);
        int x = 0, y = 0, z = 0;
        auto it = arg.begin();
        while (it != arg.end()) {
            int l = *it++, r = *it++;
            x = x * P1[r-l] % M1; x += (L1[r] - L1[l] * P1[r-l]) % M1; if (x < 0) x += M1;
            y = y * P2[r-l] % M2; y += (L2[r] - L2[l] * P2[r-l]) % M2; if (y < 0) y += M2;
            z = z * P3[r-l] % M3; z += (L3[r] - L3[l] * P3[r-l]) % M3; if (z < 0) z += M3;
        }
        return {x,y,z};
    }
    hval get(int l, int r) { return get({l,r}); }
};

void solve() {
    int n;
    string s;
    cin >> n >> s;
    Hasher h1, h2;
    h1.init(s.begin(), s.end());
    h2.init(s.rbegin(), s.rend());
    rep(i,0,n) {
        if (h1.get({0,i,i+n,2*n}) == h2.get(n-i,2*n-i)) {
            string t = s.substr(i,n);
            reverse(t.begin(), t.end());
            cout << t << "\n" << i;
            return;
        }
    }
    cout << -1;
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

相關文章