UESTC 1546(線段樹,成段更新,區間合併)

2021-06-14 08:14:24 字數 1660 閱讀 9649

這個題有一點非常重要,就是任意乙個非法的序列,我們在它的左邊新增若干個"(",右邊新增若干個")",那麼一定能夠變成乙個合法的序列。

在這裡就不證明了,比如"()))((",我們在它的左邊新增兩個"(",右邊兩個")",序列變成"((()))(())",就成了乙個合法的序列了!

因此在每乙個區間,我們記錄它缺少的左括號數needl,缺少的右括號數needr,那麼區間合併的問題就解決了。

這個題還有乙個反號操作,因此我們還要記錄每個區間反號以後缺少的左括號數tneedl,缺少的右括號數tneedr。

reverse的時候交換一下這兩個值就行了。

#include#include#includeusing namespace std;  

#define lc l,m,index<<1

#define rc m+1,r,index<<1|1

#define n 200005

struct node

seg[n<<2];

int n,q;

char str[n];

void fset(int l,int r,int index,int flag)

else//右括號

} void frev(int l,int r,int index)

void pushup(int l,int r,int index)

void pushdown(int l,int r,int index)

if(father.rev)

} void build(int l,int r,int index)

else

return;

} int m=(l+r)>>1;

build(lc);

build(rc);

pushup(l,r,index);

} void updataset(int l,int r,int flag,int l,int r,int index)

pushdown(l,r,index);

int m=(l+r)>>1;

if(r<=m)updataset(l,r,flag,lc);

else if(l>m)updataset(l,r,flag,rc);

else

pushup(l,r,index);

} void updatarev(int l,int r,int l,int r,int index)

pushdown(l,r,index);

int m=(l+r)>>1;

if(r<=m)updatarev(l,r,lc);

else if(l>m)updatarev(l,r,rc);

else

pushup(l,r,index);

} node query(int l,int r,int l,int r,int index)

} int main()

else if(op[0]=='s')

else updatarev(a,b,0,n-1,1);

} printf("\n");

} return 0;

}

線段樹成段更新 MB

include include using namespace std struct node a 4 1100000 int dp 1100000 n,m long long max long long int x,long long int y void build int l,int r,in...

Just a Hook(線段樹,成段更新)

題目傳送門 just a hook t組資料 每組有乙個長度為n的序列,給你m次操作,每次操作給你x,y,z三個數,操作 將x到y的數字變為z m次操作完成後求序列的總和 很明顯的線段樹題目,維護區間和即可 注意一下更新區間的方法即可 對於修改不能直接更新到底部,要成段更新 include usin...

線段樹(單點更新and成段更新)

線段樹需要的空間。區間為1 n 假設是一棵完全二叉樹,且樹高為i。完全二叉樹性質 第i層最多有2 i 1 個結點。那麼 2 i 1 n i log2 n 1 共有 2 i 1 個結點,即 2 log2 n 1 1個結點 即2 2 log2 n 1 2 n 1 但這是建立樹是完全二叉樹的情況下。但是如...