Codeforces 524F And Yet Another Bracket Sequence 哈希

And Yet Another Bracket Sequence

枚举起点, 增加的(肯定在最前面, 增加的)肯定在最后面, 比字典序用hash, 卡了自然溢出。。

#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; } /**/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/10990538.html