Codeforces 524F And Yet Another Bracket Sequence 哈希

And Yet Another Bracket Sequence

Enumeration starting point increase (certainly in the forefront, increasing) affirmed in the final surface, than the lexicographical with hash, cards natural overflow. .

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 2e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}

const int B = 23333;
int n; char s[N]; int a[N]; LL hs[N], powB[N], powL[N], powR[N]; int cntL[N], cntR[N]; int Log[N]; struct ST { int dp[N][21], ty; void build(int n, int b[], int _ty) { ty = _ty; for(int i = -(Log[0]=-1); i < N; i++) Log[i] = Log[i - 1] + ((i & (i - 1)) == 0); for(int i = 1; i <= n; i++) dp[i][0] = ty * b[i]; for(int j = 1; j <= Log[n]; j++) for(int i = 1; i+(1<<j)-1 <= n; i++) dp[i][j] = max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]); } inline int query(int x, int y) { int k = Log[y - x + 1]; return ty * max(dp[x][k], dp[y-(1<<k)+1][k]); } } rmq; inline LL getHash(int L, int R) { return ((hs[R] - hs[L - 1] * powB[R - L + 1] % mod) + mod) % mod; } inline LL getPosHash(int i, int len) { if(len <= cntL[i]) return powL[len]; if(len <= cntL[i] + n) return (powL[cntL[i]] * powB[len - cntL[i]] % mod + getHash(i, i + len - cntL[i] - 1)) % mod; return (powR[len - cntL[i] - n] + getHash(i, i + n - 1) * powB[len - cntL[i] - n] % mod + powL[cntL[i]] * powB[len - cntL[i]] % mod) % mod; } inline char getch(int i, int p) { if(p <= cntL[i]) return '('; else if(p <= cntL[i] + n) return s[i + p - cntL[i] - 1]; return ')'; } bool check(int p1, int p2, int len) { int low = 1, high = len, mid, p = -1; while(low <= high) { mid = low + high >> 1; if(getPosHash(p1, mid) != getPosHash(p2, mid)) p = mid, high = mid - 1; else low = mid + 1; } if(p == -1) return false; return getch(p1, p) < getch(p2, p); } int main() { for(int i = powB[0] = 1; i < N; i++) powB[i] = powB[i - 1] * B % mod; for(int i = 1; i < N; i++) powL[i] = (powL[i - 1] * B + '(') % mod; for(int i = 1; i < N; i++) powR[i] = (powR[i - 1] * B + ')') % mod; scanf("%s", s + 1); n = strlen(s + 1); for(int i = 1; i <= n; i++) s[i + n] = s[i]; for(int i = 1; i <= 2 * n; i++) hs[i] = (hs[i - 1] * B + s[i]) % mod; for(int i = 1; i <= 2 * n; i++) a[i] = a[i - 1] + (s[i] == '(' ? 1 : -1); rmq.build(2 * n, a, -1); int need = inf; for(int i = 1; i <= n; i++) { int mn = rmq.query(i, i + n - 1); if(mn < a[i - 1]) cntL[i] = a[i - 1] - mn; if(a[i + n - 1] + cntL[i] >= a[i - 1]) cntR[i] = a[i + n - 1] + cntL[i] - a[i - 1]; if(cntL[i] + cntR[i] < need) need = cntL[i] + cntR[i]; } int who = -1; for(int i = 1; i <= n; i++) { if(cntL[i] + cntR[i] > need) continue; if(who == -1) who = i; else { if(check(i, who, need + n)) who = i; } } while(cntL[who]--) putchar('('); for(int i = who; i < who + n; i++) putchar(s[i]); while(cntR[who]--) putchar(')'); puts(""); return 0; } /**/

 

Guess you like

Origin www.cnblogs.com/CJLHY/p/10990538.html