1. 程式人生 > 其它 >牛客小白月賽G (二分,字串雜湊)

牛客小白月賽G (二分,字串雜湊)

https://ac.nowcoder.com/acm/contest/11228/G

  • 列舉刪除的而後綴, 一共有兩種情況有貢獻:
  1. 剩餘的字首s是偶長度迴文串ans+1,奇長度迴文串ans+26
    2.s是隻有一個位置不迴文的迴文串,ans+2
    查詢n次判斷迴文可以用字串雜湊,難點在怎麼處理第二種情況。
  • ①二分不同點x之外的長度
  • 判斷x點到x在s中的對稱點是否為迴文串。
#include<bits/stdc++.h>
//#include <bits/extc++.h>
using namespace std;
// using namespace __gnu_cxx;
// using namespace __gnu_pbds;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);  
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
#define ull unsigned long long
#define li __int128_t
#define PII pair<int, int>
#define re register
//#define int long long
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const int mod = 1e9 + 7;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
struct str_hash {
    ull base = 131;
    ull p[N]; char s[N];
    ull mp[N];
    int n;
    void init( string &str ) {
        n = str.length();
        for ( int i = 1; i <= n; ++ i ) s[i] = str[i - 1];
        p[0] = 1;
        for ( int i = 1; i <= n; ++ i ) {
            mp[i] = mp[i - 1] * base + s[i];
            p[i] = p[i - 1] * base;
        }
    }
    ull hash ( ull l, ull r ) {
        return mp[r] - mp[l - 1] * p[r - l + 1];
    }
} nor, rev;

int main() {
    IOS
    int n; cin >> n;
    string ss; cin >> ss;
    nor.init(ss); reverse(ss.begin(), ss.end()); rev.init(ss);
    int ans = 0;
    for ( int i = 2; i <= n + 1; ++ i ) {
        int r = i - 1;
        if( nor.hash( 1, r ) == rev.hash( n - r + 1, n ) ) {
            if( r & 1 ) ans += 26; else ans += 1;
        } else {
            int lt = 0, rt = r;
            while( lt < rt ) {
                int mid = ( lt + rt + 1 ) >> 1;
                if( nor.hash(1, mid) == rev.hash( n - r + 1 , n - r + 1 + mid - 1 ) ) lt = mid;
                else rt = mid - 1;
            }
            int l = lt + 2;
            if( nor.hash( l, r - l + 1 ) == rev.hash( n - r + l, n - l + 1 ) ) {
                ans += 2;
            }
        }
    }
    cout << ans << "\n";
    return 0;
}