[BZOJ2329][HNOI2011]括號修復 平衡樹


n2 暴力能AC,類似貪心的做法,直接掃一遍就可以
誒這題目平方暴力能跑過去
只能說出題人出的數據出得真得很差,非常不用心
這種數據在比賽里對公平是多么大的一種破壞
希望比賽的出題人能夠嚴肅地對待自己出的題目
若沒有能力出好這題的數據請不要出這種題目

#include <bits/stdc++.h>
#define N 100050
using namespace std;
inline int rd() { int r; scanf("%d",&r); return r; }
int a[N],n,m,l,r;
char s[N],c[10];
int main() {
n = rd(), m = rd();
scanf("%s",s+1);
for (int _=1;_<=n;_++) a[_] = s[_] == '(' ? 1 : -1;
while (m--) {
scanf("%s",s+1);
l = rd(), r = rd();
if (s[1] == 'R') {
scanf("%s",c+1);
for (int i=l;i<=r;i++) a[i] = c[1] == '(' ? 1 : -1;
}
if (s[1] == 'S') {
int len = (r-l+1) >> 1;
for (int i=1;i<=len;i++) swap(a[l+i-1], a[r-i+1]);
}
if (s[1] == 'I') {
for (int i=l;i<=r;i++) a[i] = -a[i];
}
if (s[1] == 'Q') {
int cnt=0, ans=0;
for (int i=l;i<=r;i++) {
cnt += a[i];
if (cnt < 0) ans++, cnt += 2;
}
while (cnt > 0) cnt-=2 , ans++;
printf("%d\n",ans);
}
}
return 0;
}

標准解法就暴力放到支持區間操作的平衡樹上就行了

#include <bits/stdc++.h>
#define N 100050
using namespace std;
//splay

#define MP make_pair
#define x first
#define y second
typedef pair<int,int> pii;
struct Node{
int a,siz,sum,max[2],min[2];
int cov,swp,inv;
pii ans[4];
}tr[N];
int s[N][2],fa[N],a[N],d[N],n,m,cnt,rt;
char st[N];

// 0 無, 無
// 1取反, 無
// 2 無,翻轉
// 3取反,翻轉
inline void utax(int &x,int y) { x = max(x,y); }
inline void utin(int &x,int y) { x = min(x,y); }
inline int rd() { int r; scanf("%d",&r); return r; }

#define O tr[t]
#define L tr[ s[t][0] ]
#define R tr[ s[t][1] ]

void update(int t) {
O.siz = L.siz + R.siz + 1;
O.sum = L.sum + R.sum + O.a;

O.max[0] = L.sum + O.a;
utax(O.max[0], L.max[0]);
utax(O.max[0], L.sum + O.a + R.max[0]);

O.max[1] = R.sum + O.a;
utax(O.max[1], R.max[1]);
utax(O.max[1], R.sum + O.a + L.max[1]);

O.min[0] = L.sum + O.a;
utin(O.min[0], L.min[0]);
utin(O.min[0], L.sum + O.a + R.min[0]);

O.min[1] = R.sum + O.a;
utin(O.min[1], R.min[1]);
utin(O.min[1], R.sum + O.a + L.min[1]);

for (int _=0,tmp=-1;_<4;_++) {
O.ans[_].x = _<2 ? L.ans[_].x : R.ans[_].x;
int cur = _<2 ? L.ans[_].y : R.ans[_].y;
cur += (_&1) ? -O.a : O.a;
cur < 0 ? O.ans[_].x++,cur+=2 : 0;
_ == 0 ? tmp = cur+R.min[0], cur+=R.sum : 0;
_ == 1 ? tmp = cur-R.max[0], cur-=R.sum : 0;
_ == 2 ? tmp = cur+L.min[1], cur+=L.sum : 0;
_ == 3 ? tmp = cur-L.max[1], cur-=L.sum : 0;
-tmp > 0 ? O.ans[_].x += (-tmp+1)>>1, cur += ( (-tmp+1)>>1 ) << 1 : 0;
O.ans[_].y = cur;
}

return ;
}

int color(int t,int t1,int t2,int t3) {
if (!t1 && !t2 && !t3) return 0;
if (t1) {
O.a = t1;
O.sum = O.siz * t1;
O.max[0] = O.max[1] = max(0, O.sum);
O.min[0] = O.min[1] = min(0, O.sum);
O.cov = t1;
O.swp = 0, O.inv = 0;
if (t1 > 0) {
O.ans[0] = O.ans[2] = MP(0,O.siz);
O.ans[1] = O.ans[3] = MP((O.siz+1)>>1, O.siz&1);
} else {
O.ans[1] = O.ans[3] = MP(0,-O.sum);
O.ans[0] = O.ans[2] = MP((-O.sum+1)>>1, O.siz&1);
}
}
if (t2) {
swap(s[t][0], s[t][1]);
swap(O.ans[0], O.ans[2]);
swap(O.ans[1], O.ans[3]);
swap(O.max[0], O.max[1]);
swap(O.min[0], O.min[1]);
tr[t].swp ^= 1;
}
if (t3) {
tr[t].a = -tr[t].a; tr[t].sum = -tr[t].sum;
swap(tr[t].max, tr[t].min);
tr[t].max[0] = -tr[t].max[0];
tr[t].max[1] = -tr[t].max[1];
tr[t].min[0] = -tr[t].min[0];
tr[t].min[1] = -tr[t].min[1];
swap(O.ans[0], O.ans[1]);
swap(O.ans[2], O.ans[3]);
tr[t].inv ^= 1;
}
return 0;
}

void rotate(int x,int &k) {
int y = fa[x] , z = fa[y] , l = (s[y][0] == x) ^ 1 ,r = l ^ 1;
if (y == k) k = x; else {
if (s[z][0] == y) s[z][0] = x; else s[z][1] = x;
}
s[y][l] = s[x][r]; s[x][r] = y;
fa[y] = x; fa[x] = z; fa[ s[y][l] ] = y;
update(y), update(x);
}

void push_down(int t) {
if (s[t][0]) color(s[t][0], tr[t].cov, tr[t].swp, tr[t].inv);
if (s[t][1]) color(s[t][1], tr[t].cov, tr[t].swp, tr[t].inv);
tr[t].cov = tr[t].swp = tr[t].inv = 0;
}

stack<int> sta;
void access(int t,int k) {
while (t != k) sta.push(t), t = fa[t];
while (!sta.empty()) push_down(sta.top()), sta.pop();
}

void splay(int t,int &k) {
access(t,k);
while (t != k) {
int x = fa[t] , y = fa[x];
if (x != k) {
if ((s[y][0] == x) ^ (s[x][0] == t))
rotate(t,k);
else
rotate(x,k);
}
rotate(t,k);
}
}

void build(int l,int r,int f,int &t) {
if (!t) t = ++cnt;
int mid = (l + r) >> 1;
fa[t] = f; d[mid] = t;
tr[t].a = a[mid];
// update(t);
// if (l == r) return ;
if (l <= mid-1) build(l,mid-1,t,s[t][0]);
if (mid+1 <= r) build(mid+1,r,t,s[t][1]);
update(t);
}

void init() {
n = rd(), m = rd();
scanf("%s",st+1);
for (int _=1;_<=n;_++) a[_] = st[_]=='(' ? 1 : -1;
}

int kth(int k,int t) {
push_down(t);
int tmp = L.siz + 1;
if (k == tmp) return t;
return tmp > k ? kth(k,s[t][0]) : kth(k-tmp,s[t][1]);
}

int get(int l,int r) {
int g;
g = kth(r+2,rt);
splay(g,rt);

g = kth(l,rt);
splay(g,s[rt][0]);
return s[ s[rt][0] ][1];
}

int main() {
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
init();
build(0,n+1,0,rt);
while (m--) {
char cmd[10]; scanf("%s",cmd+1);
int l = rd(), r = rd(), g = get(l,r);
if (cmd[1] == 'R') {
char ch[5]; scanf("%s",ch+1);
color(g, ch[1]=='('?1:-1, 0, 0);
}
cmd[1] == 'S' ? color(g, 0, 1, 0) :0;
cmd[1] == 'I' ? color(g, 0, 0, 1) :0;
cmd[1] == 'Q' ? printf("%d\n",tr[g].ans[0].x + tr[g].ans[0].y/2) :0;
}
return 0;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com