Splay括號匹配(BZOJ2209)

2021-06-28 14:22:09 字數 1930 閱讀 2519

time limit: 20 sec  

memory limit: 259 mb

submit: 894  

solved: 423 [

submit][

status]

輸入資料的第一行包含兩個整數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。

思路:對於一段括號匹配結束之後肯定會成為))))((((,或者只剩一種情況,如果最後剩下的未匹配的左括號有x個,右括號有y個,那麼答案就是ans=(x+1)/2+(y+1)/2,也就是將右括號的前半部分變成左括號,左括號的後半部分變成右括號,當兩者是奇數時都需要修改。

所以伸展樹維護四個值,la表示左邊連續最小值(也就是從左邊連續匹配剩下的有括號的數量),lb表示左邊連續最大值,ra,rb類似

那麼答案就是ans=(abs(la)+1)/2+(rb+1)/2=(-la+1)/2+(rb+1)/2;

注意,這兩種形式看起來是等價的,但是後一種才是真正正確的,即包含了所有情況。因為在這裡我們會覺得在大多數時候lmin是個負數。但是有時候可能是正的,比如剩餘括號序列為((((,此時la=1,rb=4,答案為2,即將後兩個修改為右括號。

#include#include#include#include#include#includeusing namespace std;

#define key_value ch[ch[root][1]][0]

const int maxn=100010;

int ch[maxn][2],pre[maxn],rev[maxn],over[maxn],size[maxn],key[maxn];

int la[maxn],lb[maxn],sum[maxn],ra[maxn],rb[maxn];

int root,tot1;

int n,m;

char str[maxn];

void newnode(int &r,int f,int val)

void pushup(int r)

void update_rev(int r)

void update_over(int r)

void pushdown(int r)

if(over[r])

}void build(int &x,int l,int r,int f)

void init()

void rotate(int x,int kind)

void splay(int r,int goal)

else

else}}

pushup(r);

if(goal==0)root=r;

}int get_kth(int r,int k)

void debug(int r)

void reverse(int l,int r)

void over(int l,int r)

void query(int l,int r)

int main()

{ while(scanf("%d%d",&n,&m)!=eof)

{scanf("%s",str);

init();

int op,l,r;

while(m--)

{scanf("%d%d%d",&op,&l,&r);

//cout<

BZOJ2329 括號修復(Splay)

bzoj 洛谷本來想著用線段樹來寫 但是有乙個區間翻轉 所以不能用線段樹了,就只能用平衡樹 然後直接sp lay 就好了 注意一下幾個標記的下放問題 這種資料結構真的沒有什麼思路可言。include include include include include include include in...

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 內至少需要修改多少個括號才能使得兩兩匹配?這裡貌似可以認為這...

BZOJ2329 括號修復(Splay)

bzoj 洛谷本來想著用線段樹來寫 但是有乙個區間翻轉 所以不能用線段樹了,就只能用平衡樹 然後直接 splay 就好了 注意一下幾個標記的下放問題 這種資料結構真的沒有什麼思路可言。include include include include include include include in...