2022湖北省賽 J. Palindrome Reversion (字串雜湊)
阿新 • • 發佈:2022-06-01
https://codeforces.com/gym/103729/problem/J
題意: 選擇一個子串翻轉一次,問是否能得到一個迴文串
#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 int long long const int N = 1e5 + 5; const int M = 1e6 + 5; const int mod = 998244353; const ll LNF = 0x3f3f3f3f3f3f3f3f; const double PI = acos(-1.0); struct str_hash { //嚴格鴿板子 ull base = 131; ull p[N]; char s[N]; unordered_map<ull, ull> mp; // 上面可以換成陣列:ull mp[N]; int n; void init( string &str ) { n = str.length(); mp.clear(); 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() { string s; cin >> s; string ss; int len = s.length(); int st = 0; for ( int i = 0; i < len; ++ i ) { if(s[i] == s[len - i - 1]) { ++ st; } else break; } for ( int i = st; i < len - st; ++ i ) { ss += s[i]; } if(ss.size() == 0 ) { cout << 1 << " " << 1 << endl; return 0; } nor.init(ss); reverse(ss.begin(), ss.end()); rev.init(ss); int n = ss.length(); //AAP for ( int l = 1; l <= n / 2; ++ l ) { if(nor.hash(1, l) == nor.hash( 1 + l, l * 2 ) ) { int pst = 2*l + 1; if(pst == n + 1) { cout << 1 + st << " " << l + st << endl; return 0; } if( nor.hash( pst, n ) == rev.hash( 1, n - pst + 1) ) { cout << l + 1 + st << " " << n + st << endl; return 0; } } } //PAA for ( int l = 1; l <= n / 2; ++ l ) { if(rev.hash(1, l) == rev.hash( 1 + l, l * 2 ) ) { int pst = 2*l + 1; if(pst == n + 1) { cout << 1 + st << " " << l + st << endl; return 0; } if( rev.hash( pst, n ) == nor.hash( 1, n - pst + 1 ) ) { cout << 1 + st << " " << n - l + st << endl; return 0; } } } //APA for ( int l = 1; l <= n / 2; ++ l ) { if(nor.hash(1, l) == nor.hash( n - l + 1, n ) ) { int pst = l + 1; if( nor.hash( pst, n - l ) == rev.hash( pst, n - l ) ) { cout << 1 + st << " " << l + st << endl; return 0; } } } cout << -1 << " " << -1 << endl; return 0; }