牛客小白月賽G (二分,字串雜湊)
阿新 • • 發佈:2022-06-05
https://ac.nowcoder.com/acm/contest/11228/G
- 列舉刪除的而後綴, 一共有兩種情況有貢獻:
- 剩餘的字首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; }