BZOJ 2209 Jsoi2011 括號序列

2021-07-31 05:10:39 字數 1518 閱讀 4905

輸入資料的第一行包含兩個整數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 內至少需要修改多少個括號才能使得兩兩匹配?這裡貌似可以認為這...