[luogu U8984][新創無際夏日公開賽] 冰精凍西瓜 [樹狀數組]
題目背景
盛夏,冰之妖精琪露諾發現了一大片西瓜地,終於可以吃到美味的凍西瓜啦。
題目描述
琪露諾是擁有操縱冷氣程度的能力的妖精,一天她發現了一片西瓜地。這裏有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分代碼
...