CSP2019 括號樹 題解(遞推 鍊錶)

2022-03-26 10:28:01 字數 1620 閱讀 1121

前言:抽時間做了做這道題,把學長送退役的題。

題目鏈結

題目大意:定義$()$是合法括號串。如果$a,b$是合法括號串,那麼$(ab),ab$為合法括號串。現給定根節點為$1$的一棵樹,每個節點有乙個括號。定義$s_i$是從根節點到$i$結點的括號串,$k_i$是$s_i$的合法子串,求$1*k_1 \ xor \ 2*k_2 \ xor \cdots \ n*k_n$。

這道題其實實現起來並不難,重要的是思維。我也是想了快乙個小時才推出來式子qaq。

可以發現,合法的括號串模型,無非就三種:

1.$combo$式:$()()()\cdots ()$

2.套娃式:$(((((\cdots )))))$

3.混合式:$((()()\cdots ()()))$

很明顯,對於$combo$式,如果末尾再新增乙個合法括號串,那麼對答案肯定又有很多貢獻。我們先來簡單推一推式子:

假設先前有$n-1$個連續的合法括號串,現在在末尾新增了乙個。

先前的答案:$(n-1)+\frac=\frac$

現在的答案:$n+\frac=\frac$

答案增加了$n$。

這對我們來說是個好訊息,因為我們只要記錄一下先前連續的合法括號串有多少個,就可以$o(1)$求出現在的答案。

答案是不是開始浮出水面了?

對於套娃和混合式,我們把它當作乙個合法括號串,它們裡面的答案由先前的遞推來解決。

設$sum[i]$表示考慮前$i$個括號其合法的子串數量,$c[i]$表示截止到$i$為止連續的合法括號串數量。如果遇到$($,我們就讓它入棧,遇到$)$就統計答案,有遞推式:

$sum[now]=sum[fa[now]]+c[fa[st[tot]]]+1,c[now]=c[fa[st[tot]]]+1,tot--$

這樣寫對於序列沒有任何問題,但是遇到樹形結構就萎了:樹是遞迴遍歷的,用棧來維護可能會改變先前的括號順序。所以我們要用鍊錶來維護左括號序列。

剩下的就沒有什麼難的了。注意一些小細節:開long long,注意鍊錶已經是否到頭,等等。

**:

#include#define int long long

using

namespace

std;

const

int maxn=500005

;int fa[maxn],last[maxn*4

],c[maxn],sum[maxn],head[maxn],n,tot,cnt,ans;

char

ch[maxn];

struct

node

edge[maxn];

inline

intread()

while(isdigit(ch))

return x*f;

}inline

void add(int

from,int

to)inline

void dfs(int

now)

ans^=now*sum[now];

for (int i=head[now];i;i=edge[i].next)

}signed main()

dfs(1);

cout

}

CSP2019樹的重心

題解 csp2019d2t3 首先我們要明確乙個性質,那就是對於一棵樹的任何乙個節點來說,如果這個點不是重心,那麼這棵樹的重心就一定在這個節點的以重兒子為根節點的子樹裡 證明顯而易見,因為該點不是重心所以siz 重兒子 一定大於 lfloor frac rfloor 另外還有乙個重心的定義 重心所有...

CSP2019 樹的重心

點這裡看題目。原來資料的奇怪結尾就可以拿來判斷特徵呀 太簡單就不說了。考慮完全二叉樹怎麼做。這裡需要注意一點,就是 n 262143 2 1 也就是說,資料實際上就是一棵滿二叉樹。由於滿二叉樹具有極強的對稱性,我們不難想到這樣解決 首先,答案一定包含 frac rt 其中 rt 是樹的根。考慮根的左...

CSP2019模擬 五彩樹

給定一顆n nn個節點的樹,每個節點有 1,m 1,m 1,m 中的一種顏色,求乙個包含不少於k kk種顏色的連通塊,使其它節點到該連通塊最短路徑的最大值最大。資料範圍 n,m 1000000 n,m le 1000000 n,m 10 0000 0 如果已經確定乙個到連通塊最短路徑最大的節點p p...