首页 > 代码库 > [luogu U8984][新创无际夏日公开赛] 冰精冻西瓜 [树状数组]

[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:
41 2 1.000000002 3 0.000000003 4 1.0000010191 1 3.000000009 29 31 2 1.428560319 49 21 3 4.233333339 29 4
输出样例#1:
3.000000000.000000000.000000004.428560314.428560314.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分代码

...

标签上写树状数组来着,可是我不会啊  QwQ

过两天等题解出来再放吧

[luogu U8984][新创无际夏日公开赛] 冰精冻西瓜 [树状数组]