http://www.lydsy.com/JudgeOnline/problem.php?id=2209
Splay again make fun ... The sum of UPD1 there forgot to assign the inverse ....
Good god. ((((() (((((((((((((() ((((((() (((The
And the subject of the query to the length of the interval as an even number ....
If you can tell how many are there and how many (, then the answer is
) is divided by 2 to the upper bound + (the number divided by the upper bound of 2
It's very simple ...
So we only need to maintain the splay from the left to the maximum number of, left (up to how many can be.)
However, due to the existence of Operation 2 and Operation 3, we also need to maintain the left continuous (up to how many, to the right) the maximum number of, so that can support the.
then please yourself yy
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream > #include <algorithm> #include <queue> #include <set> #include <map>using namespace std; typedef long Long LL; #define REP (i, n) for (int i=0; i< (n); ++i) #define FOR1 (i,a,n) for (int i= (a); i<= (n); ++i) #define For2 (i,a,n) for (int i= (a);i< (n), ++i) #define FOR3 (i,a,n) for (int i= (a); i>= (n); i.) #define FOR4 (i,a,n) for (int i= ( a);i> (n); i) #define CC (i,a) memset (i,a,sizeof (i)) #define READ (a) a=getint () #define PRINT (a) printf ("%d", a) # Define DBG (x) cout << (#x) << "=" << (x) << endl#define error (x) (! x) puts ("error"): 0) #define RDM (x, i) for (int i=ihead[x]; i; i=e[i].next) inline const int Getint () {int r=0, k=1; Char c=g Etchar (); for (; c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') k=-1; for (; c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) r=r*10+c-' 0 '; return k*r; }const int oo=~0u>>1, n=1e5+10;struct node *null;struct node {node *f, *c[2];int s, K, Lmin, Lmax, Rmin, Rmax, sum;bool tag, rev;node (int _k=0) {s=1; lmin=lmax=rmin=rmax=k=sum=_k; f =c[0]=c[1]=null; tag=rev=0; }void setc (node *x, bool D) {c[d]=x; x->f=this;} BOOL D () {return f->c[1]==this;} void Pushup () {s=c[0]->s+c[1]->s+1;sum=c[0]->sum+c[1]->sum+k;lmin=c[0]->lmin;lmax=c[0]->lmax; Rmin=c[1]->rmin;rmax=c[1]->rmax;int mnl=min (0, C[1]->lmin), mnr=min (0, c[0]->rmin); int Mxl=max (0, c[1]- >lmax), Mxr=max (0, C[0]->rmax); Lmin=min (Lmin, C[0]->SUM+K+MNL); Lmax=max (Lmax, C[0]->SUM+K+MXL); rmin= Min (rmin, C[1]->SUM+K+MNR); Rmax=max (Rmax, C[1]->SUM+K+MXR);} void Upd1 () {if (this==null) Return;tag=!tag;int t=lmin;lmin=-lmax;lmax=-t;t=rmin;rmin=-rmax;rmax=-t;k=-k;sum=-sum;} void Upd2 () {if (this==null) Return;rev=!rev;swap (c[0], c[1]), swap (Lmin, rmin), swap (Lmax, rmax);} void Pushdown () {if (tag) {TAG=0;C[0]->UPD1 (); C[1]->upd1 ();} if (rev) {rev=0;c[0]->upd2 (); C[1]->upd2 ();}}} *root;void PN (node *x) {printf("key:%c \ t lmin:%d \ lmax:%d \ rmin:%d \ t rmax:%d \ t sum:%d \ n", x->k==1? (':(x->k==-1 ') ': ' N '), X->lmin, X->lmax, X->rmin, X->rmax, x->sum);} void Pr (node *x) {if (x==null) return; Pr (x->c[0]); if (x->k) printf ("%c", x->k==1? ' (‘:‘)‘); Pr (x->c[1]);} void P (node *x=root) {Pr (x); puts ("");} void Rot (node *x) {node *f=x->f;f->pushdown (); X->pushdown (); bool D=x->d (); f->f->setc (x, F->d ()) ; F->setc (X->c[!d], D); X->setc (f,!d); F->pushup (); if (F==root) root=x;} void splay (node *x, node *f=null) {X->pushdown (); while (x->f!=f) if (x->f->f==f) rot (x); else x->d () ==x- >f->d ()? (Rot (x->f), rot (x)):(rot (x), rot (x)); X->pushup (); Node *sel (node *x, int k) {if (x==null) return X;x->pushdown (); int s=x->c[0]->s;if (S==K) return x;if (s<k) Retu RN sel (x->c[1], k-s-1); return sel (X->c[0], k);} Node *getrange (int l, int r) {splay (sel (root, L-1)), splay (sel (Root, r+1), root); return root->c[1]->c[0];} void Fix1 ({int L=getint (), R=getint (), node *x=getrange (l, R); X->pushdown (); X->upd1 ();} void Fix2 () {int l=getint (), R=getint (), node *x=getrange (l, R); X->pushdown (); X->upd2 ();} void Ask () {int l=getint (), R=getint (), node *x=getrange (l, R), l= (-x->lmin+1) >>1;r= (x->rmax+1) >>1; printf ("%d\n", L+r);} Char S[n];int N, M, q;void build (int l, int r, node *&x) {if (l>r) Return;int mid= (L+r) >>1;x=new node (s[mid]== '? -1:1), if (l==r) Return;build (L, Mid-1, x->c[0]); Build (Mid+1, R, X->c[1]); if (l<=mid-1) x->c[0]->f=x ; if (mid+1<=r) X->c[1]->f=x;x->pushup ();} void in (node *x) {x->lmax=x->rmax=-oo;x->lmin=x->rmin=oo;x->sum=0;x->k=0;} void Init () {null=new node (); null->s=0; in (null), Null->f=null->c[0]=null->c[1]=null;root=new node (); In ( root); Root->setc (new Node (), 1); In (root->c[1]); node *x;read (n); Read (m); scanf ("%s", s+1), build (1, N, x), root->c[1]->setc (x, 0); Root->c[1]->pushup (); Root->pushup ();} INT Main () {init (); while (m--) {int c=getint (); if (c==0) ask (); else if (c==1) fix1 (); else if (c==2) fix2 ();} return 0;}
The first line of the Descriptioninput input data contains two integers n and q, each representing the length of the bracket sequence and the number of operations. The second line contains a sequence of parentheses with a length of N. Next Q line, each line of three integers t, x and Y, respectively, indicating the type of operation, the starting position of the operation and the end position of the operation, the input data guaranteed x is not less than Y. Where t=0 indicates an inquiry operation, T=1 represents a reversal operation, and t=2 represents a rollover operation. Output for each query operation, a line is shown that indicates the minimum number of changes required to modify the sequence of parentheses to match the subsequence. Sample INPUT6 3
)(())(
0 1 6
0 1 4
0 3 4 Sample Output2
2
0
HINT
100% of data meet n,q not more than 10^5
。
Source
First round
"Bzoj" 2209: [Jsoi2011] Bracket sequence (splay)