1. 程式人生 > >[luogu U8984][新創無際夏日公開賽] 冰精凍西瓜 [樹狀數組]

[luogu U8984][新創無際夏日公開賽] 冰精凍西瓜 [樹狀數組]

def 輸出 png namespace name using string back 註意

題目背景

技術分享

盛夏,冰之妖精琪露諾發現了一大片西瓜地,終於可以吃到美味的凍西瓜啦。

題目描述

琪露諾是擁有操縱冷氣程度的能力的妖精,一天她發現了一片西瓜地。這裏有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
9
1 1 3.00000000
9 2
9 3
1 2 1.42856031
9 4
9 2
1 3 4.23333333
9 2
9 4
輸出樣例#1:
3.00000000
0.00000000
0.00000000
4.42856031
4.42856031
4.23333761

說明

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

“西瓜樹”退化為一條鏈

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

技術分享

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

(樣例中的冷氣寒冷程度的範圍為[1,5])


20分代碼

n<=1000 m<=1000

好小的樹

--->樸素的、完全依照題意的遍歷樹算法

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<vector>
 5 #include<cmath>
 6 using namespace std;
 7 
 8 inline int read(){
 9     int re=0;
10     char ch;
11     bool flag=0;
12     while((ch=getchar())!=-&&(ch<0||ch>9));
13     ch==-?flag=1:re=ch-0;
14     while((ch=getchar())>=0&&ch<=9)  re=(re<<1)+(re<<3)+ch-0;
15     return flag?-re:re;
16 }
17 
18 typedef long double lb;
19 
20 struct edge{
21     int to,next;
22     lb w;
23     edge(int to=0,int next=0,lb w=0):
24         to(to),next(next),w(w){}
25 };
26 
27 const int maxn=100001;
28 
29 const lb eps=1e-8;
30 vector<edge> edges;
31 vector<edge> tree;
32 int n,m,cnt,root=1;
33 int head[maxn],tmp_head[maxn];
34 lb data[maxn];
35 
36 bool oo(lb ww){
37     if(fabs(ww)<eps)  return 0;
38     return 1;
39 }
40 
41 inline void add_edge(int from,int to,lb w){
42     edges.push_back(edge(to,head[from],w));
43     head[from]=++cnt;
44     edges.push_back(edge(from,head[to],w));
45     head[to]=++cnt;
46 }
47 
48 inline void add_tree(int from,int to,lb w){
49     tree.push_back(edge(to,tmp_head[from],w));
50     tmp_head[from]=++cnt;
51 }
52 
53 void dfs_tree(int x,int fa){
54     for(int ee=head[x];ee;ee=edges[ee].next)
55         if(edges[ee].to!=fa){
56             add_tree(x,edges[ee].to,edges[ee].w);
57             dfs_tree(edges[ee].to,x);
58         }
59 }
60 
61 void dfs(int ss,lb ww){
62     data[ss]+=ww;
63     for(int ee=head[ss];ee;ee=tree[ee].next)
64         if(oo(tree[ee].w))
65             dfs(tree[ee].to,ww*tree[ee].w);
66 }
67 
68 int main(){
69     //freopen("temp.in","r",stdin);
70     cnt=0;
71     n=read();
72     edges.push_back(edge(0,0,0));
73     for(int i=1;i<n;i++){
74         int from=read(),to=read();
75         lb w;scanf("%Lf",&w);
76         add_edge(from,to,w);
77     }
78     cnt=0;
79     tree.push_back(edge(0,0,0));
80     dfs_tree(root,0);
81     swap(head,tmp_head);
82     m=read();
83     for(int i=0;i<m;i++){
84         int op=read(),ss=read();
85         if(op&8){
86             printf("%.8Lf\n",data[ss]);
87         }
88         else{
89             lb ww;scanf("%Lf",&ww);
90             dfs(ss,ww);
91         }
92     }
93     return 0;
94 }

100分代碼

...