有n+
1 顆樹,編號為t0
~tn ,對於每一棵樹ti,他在第ta
i 棵樹的第ci
個點和第tb
i 棵樹的第di
個點之間連上了一條長度為le
ni的邊。在ti
中,他保持ta
i 中的所有節點編號不變,把tb
i 中的所有節點的編號加上si
zeai
。 我們定義一棵樹的美觀度為兩兩點之間的距離之和,現在要輸出所有樹的美觀度。
我們可以模擬這個樹的構成過程,然後把他們全部存下來。
對於美觀度暴力遍歷整棵樹,加起來。
這題其實是很隱蔽的搜尋題
仔細想想,這棵樹其實是之前的兩棵樹的組合,我們有必要知道整棵樹嗎?
我們只需要知道是哪顆樹就行了。
我們看當前這棵樹。
我們已知他的左兒子是ta
,右兒子是tb
,連線點是
x ,y,
suma
,sum
b (美觀度),si
zea ,si
zeb (節點數),連線的邊長度為藍色那條邊為le
n 。
我們不妨再設d[
t][i
] 表示第
t 棵樹,編號為
i的節點到整棵樹的距離和。
至此,我們再結合d[
a][x
] ,d[
b][y
] ,我們不難推出su
mi。 問題s
uma ,su
mb是子問題,之前一定會處理過的。
那麼我們剩下的問題就是d[
t][i
] 怎麼求了。
我們設乙個狀態di
s[t]
[i][
j]表示樹
t 裡編號為
i的點到編號
j 的點的距離。
我們可以通過di
s[t]
[i][
j]來在每次合併的時候推出d[
t][i
] d[
t][i
] 就是現在的d[
t][i
] 加上多出來的子樹到其關鍵點的距離和加上le
n 的其si
ze倍再加上自己到自己所在子樹的關鍵點的距離的si
ze倍。
比較繞口但是也就這樣了。
直接存下來肯定是不現實的。全部都轉移也是不現實的。
怎麼辦?
觀察發現,有效的點實質上很少。
我們用得上的
x ,
y都是題目給出的。
我們把這些點叫為關鍵點。
你是不是已經知道怎麼做了呢?
我們只存下關鍵點的相關狀態。
什麼叫相關狀態呢?比如我這顆樹把
x 標記為關鍵點,為了更新
x,我們必須在之前的樹里都一直維護
x 的資訊,遞迴下去,把標記都打上,這就是這個關鍵點的相關狀態。
我們有n
棵樹,每棵樹最多標記2∗
n 個點,總共只有n∗
n∗2 個關鍵點 di
s[t]
[i][
j]的轉移是o(
n2) ,d[
t][i
] 轉移是o(
n)每棵樹都要更新狀態,總的時間複雜度是o(
n3)
這題非常靈活地運用了記憶化搜尋的遞迴性質。
其實這和一些常見的最短路只存關鍵點狀態是相似的。
只存關鍵點。
由於有點難理解所以我貼下**。
#include
#include
#include
using namespace std
;typedef pairpi;
typedef long long ll;
const int n = 130 , mo = 1e9 + 7
;pi bz[n][n];
struct nodeq[n];
ll size[n],dis[n][n][n],d[n][n];
int n,fi[n];
int mark(int x , ll p)
void solve()
for (int i = 2
; i <= n ; i ++)
int b , b1;
b = (!p.first) ? q[i].a : q[i].b
; b1 = (!p1.first) ? q[i].a : q[i].b
; dis[i][j][k] = ((dis[q[i].s[p.first]][b][p.second] + dis[q[i].s[p1.first]][b1][p1.second]) % mo + len ) % mo;}}
lch = q[i].a , rch = q[i].b
; for (int j = 1
; j <= fi[i] ; j ++)
lch = q[i].s[0], rch = q[i].s[1];
q[i].sum = d[lch][q[i].a] * size[rch] % mo;
(q[i].sum += d[rch][q[i].b]* size[lch] % mo) %= mo;
q[i].sum = q[i].sum + size[lch] * size[rch] % mo * len % mo;
q[i].sum = (q[i].sum + q[lch].sum) % mo + q[rch].sum % mo;
q[i].sum %= mo;
printf("%i64d\n" , q[i].sum);
}}int main()
清華冬令營2018模擬 送你一棵聖誕樹
對於每個詢問輸出一行乙個整數,表示答案.5 5 0 5 5 2 5 5 5 1 2 5 4 2 3 5 1 2 2 3 2 5 1 1 1 1 5 2 3 2 1 3 1 5 0 3 15 5 1 4 1 1 5 4 5 1 3 5 2 3 4 3 2 5 4 2 2 2 1 3 1 5 2 1 2...
送你一朵聖誕樹
貪心解決。這種考慮前後順序的題目的常見做法是前後比較將優先順序排序,再用並查集輔助合併。善用stl 如果要維護乙個堆的話,可以用set,最方便,stl的heap太麻煩,優先佇列可能被卡。注意,set中如果自定義了比較函式 還是比較複雜的那種,如本題的貪心 那麼set.find 很有可能re 不是找不...
教你用Python畫了一棵聖誕樹
如何用python畫乙個聖誕樹呢?最簡單 height 5 stars 1for i in range height print height i stars stars 2 print height 效果 哈哈哈哈,總有一種騙了大家的感覺。其實本文是想介紹turtle庫來畫聖誕樹。import t...