輸入資料的第一行包含兩個整數n和q,分別表示括號序列的長度,以及操作的個數。 第二行包含乙個長度為n的括號序列。 接下來q行,每行三個整數t、x和y,分別表示操作的型別、操作的開始位置和操作的結 束位置,輸入資料保證x不小於y。其中t=0表示詢問操作、t=1表示反轉操作、t=2表示翻轉操 作。
對於每乙個詢問操作,輸出一行,表示將括號序列的該子串行修改為配對,所需的最少改動 個數。
6 3)(())(
0 1 6
0 1 4
0 3 4 22
0100%的資料滿足n,q不超過10^5
。第一輪
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
splay~
翻轉和反轉都是splay的基本操作,主要的就是如何求一段括號序列的修改的最小值。假設一段括號序列已經化簡(去掉能匹配的),剩下的括號一定是偶數個。如果有x個'(',y個')',那麼當x為奇數時,答案為(x+1)/2+(y+1)/2,當x為偶數時,答案為x/2+y/2。所以答案就是(x+1)/2+(y+1)/2。
xy 怎麼求?根據lych神犇的部落格,令'('==1,')'==-1,那麼x=最小左子段和,y=最大右子段和,我們維護每乙個點的最小/大左/右子段,同時為了維護我們還要記錄num[i]即每個點及其子樹的值之和,然後用放進splay裡就可以了。
(最後輸出的時候用((val[x].r1+1)>>1)-((val[x].l0-1)>>1)就是wa的……為什麼……)
splay建樹的時候前面要空一位!陣列要開大點!
#include#includeusing namespace std;
#define mid (l+r>>1)
int n,m,t,x,y,a[110001],num[110001],c[110001][2],fa[110001],siz[110001],cnt,root;
bool rev[110001],tag[110001];
char s[110001];
struct nodeval[100001];
int read()
while(ch>='0' && ch<='9')
return x*f;
}void pushup(int u)
void rever(int u)
void chantag(int u)
void pushdown(int u)
if(rev[u]) }
void build(int l,int r,int &k,int last)
build(l,k-1,c[k][0],k);build(k+1,r,c[k][1],k);
pushup(k);
}void rotate(int x,int &k)
void splay(int x,int &k)
rotate(x,k); }}
int findd(int u,int k)
int main()
return 0;
}
2209 Jsoi2011 括號序列
輸入資料的第一行包含兩個整數n和q,分別表示括號序列的長度,以及操作的個數。第二行包含乙個長度為n的括號序列。接下來q行,每行三個整數t x和y,分別表示操作的型別 操作的開始位置和操作的結 束位置,輸入資料保證x不小於y。其中t 0表示詢問操作 t 1表示反轉操作 t 2表示翻轉操 作。對於每乙個...
Splay括號匹配(BZOJ2209)
time limit 20 sec memory limit 259 mb submit 894 solved 423 submit status 輸入資料的第一行包含兩個整數n和q,分別表示括號序列的長度,以及操作的個數。第二行包含乙個長度為n的括號序列。接下來q行,每行三個整數t x和y,分別表...
BZOJ 2209 括號序列(splay)
題意 給出乙個括號序列,僅包含 和 三種操作 1 將 l,r 區間內的括號反轉,即 變為 變為 2 將 l,r 區間內的括號翻轉,之前為a l a l 1 a r 1 a r 現在為a r a r 1 a l 1 a l 3 詢問 l,r 內至少需要修改多少個括號才能使得兩兩匹配?這裡貌似可以認為這...