bzoj 1095(括號序列)

2021-08-05 21:47:30 字數 1517 閱讀 2464

傳送門

括號序列:訪問到乙個點時,加入』(『,再加入該點編號,訪問完這個點及其子樹退出時加入』)』

括號序列有乙個神奇的性質:任意兩點間的距離即為括號序列中將它們之間可匹配的括號全部消去後,剩下的括號的數量。為什麼呢???把序列中可以匹配的括號消去後,剩餘的括號肯定是」)))…..)(……(((「這樣的。』)』的個數就是x到lca(x,y)的距離,』(『的個數就是y到lca(x,y)的距離。

用線段樹維護括號序列,線段樹每個結點維護七個元素:

s1:」(「的個數

s2:」)」的個數

l1:左段括號數量最大值(去除匹配括號的)

r1:右段括號數量最大值

l2:左段」(「個數與」)」個數之差最大值

r2:右段」)」個數與」(「個數之差最大值

ans:該區間內去匹配括號後」(「個數與」)」個數之和的最大值。

#include

#define lson rt<<1,l,mid

#define rson rt<<1|1,mid+1,r

#define root 1,1,tim

using

namespace

std;

const

int maxn=1e5+2,inf=0x3f3f3f3f;

int n,m,mark[maxn],cnt;

struct node

inline

void pushup(node &l,node &r)

}s[maxn*3

<<2];

int num[maxn*3],tim=0;

int head[maxn],edge=0,pos[maxn];

struct edge e[maxn<<1];

inline

void adde(int u,int v)

void dfs(int p,int fa)

num[++tim]=-2;

}void modify(int rt,int l,int r,int p)

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

if (p<=mid) modify(lson,p);

else modify(rson,p);

s[rt].pushup(s[rt<<1],s[rt<<1|1]);

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

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

build(lson),

build(rson),

s[rt].pushup(s[rt<<1],s[rt<<1|1]);

}inline

int read()

int main()

dfs(1,0);

build(root);

m=read();

for (register

int i=1;i<=m;++i)

else

}return

0;}

BZOJ 1095 捉迷藏 動態點分治 點分樹

1095 zjoi2007 hide 捉迷藏 time limit 40 sec memory limit 256 mb submit 4152 solved 1756 submit status discuss description 捉迷藏 jiajia和wind是一對恩愛的夫妻,並且他們有很多...

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

BZOJ 2209 Jsoi2011 括號序列

輸入資料的第一行包含兩個整數n和q,分別表示括號序列的長度,以及操作的個數。第二行包含乙個長度為n的括號序列。接下來q行,每行三個整數t x和y,分別表示操作的型別 操作的開始位置和操作的結 束位置,輸入資料保證x不小於y。其中t 0表示詢問操作 t 1表示反轉操作 t 2表示翻轉操 作。對於每乙個...