冰精凍西瓜 P3787洛谷

2022-05-12 12:19:09 字數 3026 閱讀 8087

琪露諾是擁有操縱冷氣程度的能力的妖精,一天她發現了一片西瓜地。這裡有n個西瓜,由n-1条西瓜蔓連線,形成乙個有根樹,琪露諾想要把它們冷凍起來慢慢吃。

這些西瓜蔓具有神奇的性質,可以將經過它的冷氣的寒冷程度放大或縮小,每條西瓜蔓放大/縮小冷氣寒冷程度的能力值為wi,表示冷氣經過它後,寒冷程度值x會變為x*wi。每個西瓜也有乙個寒冷程度值,炎熱的夏日,所有西瓜的寒冷程度值初始都為0。

琪露諾會做出兩種動作:

①.對著西瓜i放出寒冷程度為x的冷氣。這股冷氣順著西瓜蔓向「西瓜樹」的葉子節點蔓延,冷氣的寒冷程度會按照上面的規則變化。遇到乙個西瓜連了多條西瓜蔓時,每條葉子節點方向的西瓜蔓均會獲得與原先寒冷程度相等的冷氣。途徑的所有西瓜的寒冷程度值都會加上冷氣的寒冷程度值。

⑨.向你詢問西瓜i的寒冷程度值是多少。

等等,為什麼會有⑨?因為笨蛋琪露諾自己也會忘記放了多少冰呢。

所以,幫她計算的任務就這麼交給你啦。

輸入格式:

第一行乙個整數n,表示西瓜的數量。

西瓜編號為1~n,1為這棵「西瓜樹」的根。

接下來n-1行,每行有兩個整數u,v和乙個實數w,表示西瓜u和西瓜v之間連線有一條藤蔓,它放大/縮小冷氣寒冷程度的能力值為w。

接下來一行乙個整數m,表示操作的數量。

接下來m行,每行兩個或三個整數。

第乙個數只能是1或9。

如果為1,接下來乙個整數i和乙個實數x,表示對西瓜i放出寒冷程度為x的冷氣。

如果為9,接下來乙個整數i,表示詢問編號為i的西瓜的寒冷程度值。

輸出格式:

對於每個操作⑨,輸出一行乙個實數,表示對應西瓜的寒冷程度值。

輸入樣例#1:

4

1 2 1.00000000

2 3 0.00000000

3 4 1.00000101

91 1 3.00000000

9 29 3

1 2 1.42856031

9 49 2

1 3 4.23333333

9 29 4

輸出樣例#1:

3.00000000

0.00000000

0.00000000

4.42856031

4.42856031

4.23333761

子任務可能出現如下的特殊性質:

「西瓜樹」退化為一條鏈

輸入資料中的實數均保留8位小數,選手的答案被判作正確當且僅當輸出與標準答案誤差不超過10^-7。請特別注意浮點數精度問題。

實際資料中,冷氣的寒冷程度x的範圍為 [-0.1,0.1]

題解:

很巧妙的樹狀陣列,線段樹也可以

首先運用了「砍樹」思想,因為當wi=0時,該邊無法傳遞凍氣。將整棵樹以wi=0的

邊為界,分成多棵樹,每一棵樹都求dfs並編號,記錄乙個點影響的區間(子樹)

in[i]~out[i](就是子樹dfs序號的範圍,當然包括自己),

並記下每個點到該樹的根的w之積

對於操作①,可以這麼想,如果所有冷氣都是從樹根釋放出來的,

那麼冷凍值可以直接累加起來,最後乘以ki就能得到任意子節點的冷凍值

因此我們可以把每個操作①看做從樹根釋放的,那麼冷凍值就是x/ki。

所以只要給冷氣釋放的節點和其子樹都增加x/ki即可。

由於有線段樹的支援,所以單次操作時間複雜度是o(logn)

對於操作⑨,只要輸出樹狀陣列(線段樹)上對應節點的值乘以ki即可,時間複雜度也是o(logn)

如果不砍樹,則該點的凍氣的就會往wi=0的下面蔓延,不合題意。

(此處wi指邊權,ki指樹根到i的wi之積,與**變數有出入)

1 #include2 #include3 #include4 #include5 #include6 #include7

#define ld double

8using

namespace

std;

9int

n,m;

10 vectorg[100005

];11 vectordis[100005

];12

const ld eps=1e-8

;13 queueq;

14bool vis[100005

];15

intin[100005],cnt,out[100005

];16 ld c[100005],w[100005

];17

void add(int u,int

v,ld d)

1822

void dfs(int

x)23

34else

if (vis[g[x][i]]==0)35

q.push(g[x][i]);36}

37out[x]=cnt;38}

39void update(int

x,ld d)

40 44 ld query(int

x)45

51int

main()

52 60 q.push(1

);61 cnt=0;62

while (!q.empty())

6368 scanf("

%d",&k);

69for (i=1;i<=k;i++)

7080

else

8185

}86 }

luogu P3787 冰精凍西瓜

嘟嘟嘟 好題,好題 看這個修改和詢問,就知道要麼是求完dfs序後線段樹維護,要麼是樹剖。又因為這道題都是子樹的操作,沒有鏈上的,所以線段樹就夠了。然而重點不是這個。這道題最麻煩的是線段樹pushdown時對於每乙個節點打的標記都不一樣,因為每一條邊上的能力值不一樣。這也是這道題最巧妙的一點 我們把每...

Luogu3787 冰精凍西瓜(樹上操作)題解

這題面不禁讓我聯想到了樹剖 思路顯然,這道題並不需要樹剖畢竟它只是藍題,不過,它也需要用到 dfs 序,把樹上操作轉化成序列操作 這個思想可以說很套路了 但這題有乙個麻煩的地方 在修改子樹時每一條邊都會對修改值造成影響,而這用線段樹是難以維護的。於是我們考慮將邊上的影響分離出來,可以先預處理出乙個從...

洛谷P1601 A B Problem(高精)

高精度加法,x相當於a b problem,b color red 不用考慮負數 color b 輸入格式 分兩行輸入a,b 10 500 輸出格式 輸出只有一行,代表a b的值 輸入樣例 1 複製 1 1輸出樣例 1 複製 2思路 顯而易見是通過陣列來模擬,之前寫過類似的,直接用了,不過以前寫的太...