[Luogu 3787] 冰精冻西瓜
Description
琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地。这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有根树,琪露诺想要把它们冷冻起来慢慢吃。
这些西瓜蔓具有神奇的性质,可以将经过它的冷气的寒冷程度放大或缩小,每条西瓜蔓放大/缩小冷气寒冷程度的能力值为Wi,表示冷气经过它后,寒冷程度值x会变为x*wi。每个西瓜也有一个寒冷程度值,炎热的夏日,所有西瓜的寒冷程度值初始都为0。
琪露诺会做出两种动作:
①.对着西瓜i放出寒冷程度为x的冷气。这股冷气顺着西瓜蔓向“西瓜树”的叶子节点蔓延,冷气的寒冷程度会按照上面的规则变化。遇到一个西瓜连了多条西瓜蔓时,每条叶子节点方向的西瓜蔓均会获得与原先寒冷程度相等的冷气。途径的所有西瓜的寒冷程度值都会加上冷气的寒冷程度值。
⑨.向你询问西瓜i的寒冷程度值是多少。
等等,为什么会有⑨?因为笨蛋琪露诺自己也会忘记放了多少冰呢。
所以,帮她计算的任务就这么交给你啦。
Input
第一行一个整数n,表示西瓜的数量。
西瓜编号为1~n,1为这棵“西瓜树”的根。
接下来n-1行,每行有两个整数u,v和一个实数w,表示西瓜u和西瓜v之间连接有一条藤蔓,它放大/缩小冷气寒冷程度的能力值为w。
接下来一行一个整数m,表示操作的数量。
接下来m行,每行两个或三个整数。
第一个数只能是1或9。
如果为1,接下来一个整数i和一个实数x,表示对西瓜i放出寒冷程度为x的冷气。
如果为9,接下来一个整数i,表示询问编号为i的西瓜的寒冷程度值。
Output
对于每个操作⑨,输出一行一个实数,表示对应西瓜的寒冷程度值。
Solution
对于那些边权为0的边,显然只有从这条边下面出发的冷气才能对这棵子树有贡献。所以不妨将所有边权为0的边看作不存在的边,将这棵树划分成几个内部边权都不为0的联通块,易证,每个联通块都是一棵树。
然后dfs一遍求出每棵树内每个点到根节点的边权之积,也就是说,求出如果有一个寒冷程度为1的冷气从根节点出发, 到达每个节点的寒冷程度贡献要求出来为 dis。
然后就可以线段树做了。
ps:因为dis是从根节点出发到当前这个点的乘积,所以修改的时候要用读入的y除以当前的dis才是真正要改的值。
编辑器换了字体心情都好起来了
Code
#include<cstdio>
#include<cctype>
#include<vector>
#define N 100005
#define db double
#define min(A,B) ((A)<(B)?(A):(B))
#define max(A,B) ((A)>(B)?(A):(B))
#define swap(A,B) ((A)^=(B)^=(A)^=(B))
db dis[N];
int n,cnt,m;
db ch[N<<2];
std::vector<int> son;
int dfn[N],tot,sze[N];
db sum[N<<2],lazy[N<<2];
int head[N],vis[N],fs[N];
struct Edge{
int to,nxt;
db dis;
}edge[N<<1];
void add(int x,int y,db z){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
edge[cnt].dis=z;
head[x]=cnt;
}
int getint(){
int x=0,f=0;char ch=getchar();
while(!isdigit(ch)) f|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x;
}
void dfs2(int now){
sze[now]=1;dfn[now]=++tot;fs[tot]=now;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(sze[to]) continue;
if(edge[i].dis==0){
son.push_back(to);
continue;
}
dis[to]=edge[i].dis*dis[now];
dfs2(to);
sze[now]+=sze[to];
}
}
void build(int cur,int l,int r){
if(l==r){
ch[cur]=dis[fs[l]];
return;
}
int mid=l+r>>1;
build(cur<<1,l,mid);
build(cur<<1|1,mid+1,r);
ch[cur]=ch[cur<<1]+ch[cur<<1|1];
}
void pushdown(int cur){
if(lazy[cur]==0) return;
sum[cur<<1]+=lazy[cur]*ch[cur<<1];
sum[cur<<1|1]+=lazy[cur]*ch[cur<<1|1];
lazy[cur<<1]+=lazy[cur];
lazy[cur<<1|1]+=lazy[cur];
lazy[cur]=0;
}
void modify(int cur,int l,int r,int ql,int qr,db c){
if(ql<=l and r<=qr){
sum[cur]+=c*ch[cur];
lazy[cur]+=c;
return;
}
int mid=l+r>>1;
pushdown(cur);
if(ql<=mid)
modify(cur<<1,l,mid,ql,qr,c);
if(mid<qr)
modify(cur<<1|1,mid+1,r,ql,qr,c);
sum[cur]=sum[cur<<1]+sum[cur<<1|1];
}
db query(int cur,int l,int r,int ql,int qr){
if(ql<=l and r<=qr)
return sum[cur];
pushdown(cur);
int mid=l+r>>1;
if(ql<=mid)
return query(cur<<1,l,mid,ql,qr);
else
return query(cur<<1|1,mid+1,r,ql,qr);
}
signed main(){
n=getint();
for(int i=1;i<n;i++){
int x=getint(),y=getint();
db z;scanf("%lf",&z);
add(x,y,z);add(y,x,z);
}
son.push_back(1);
for(int i=0;i<son.size();i++)
dis[son[i]]=1.0,dfs2(son[i]);
build(1,1,n);
m=getint();
while(m--){
if(getint()==1){
int x=getint();
db y;scanf("%lf",&y);
modify(1,1,n,dfn[x],dfn[x]+sze[x]-1,y/dis[x]);
} else{
int x=getint();
printf("%.8lf\n",query(1,1,n,dfn[x],dfn[x]));
}
}
return 0;
}
[Luogu 3787] 冰精冻西瓜的更多相关文章
- luogu P3787 冰精冻西瓜
嘟嘟嘟 好题,好题…… 看这个修改和询问,就知道要么是求完dfs序后线段树维护,要么是树剖.又因为这道题都是子树的操作,没有链上的,所以线段树就够了. 然而重点不是这个.这道题最麻烦的是线段树push ...
- [luogu P3787][新创无际夏日公开赛] 冰精冻西瓜 [树状数组][dfs序]
题目背景 盛夏,冰之妖精琪露诺发现了一大片西瓜地,终于可以吃到美味的冻西瓜啦. 题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有 ...
- [Luogu3787] 冰精冻西瓜
题目背景 盛夏,冰之妖精琪露诺发现了一大片西瓜地,终于可以吃到美味的冻西瓜啦. 题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有 ...
- 【Luogu】P3787冰精冻西瓜(线段树)
题目链接 我脑子怕不是有坑qwqqq 用前缀和思想,dis[i]表示i离根的距离,那么修改操作其实是对x的子树区间加y/dis[x],查询的时候*dis[to]即可. 对付/0错的思路是建森林,然而这 ...
- 冰精冻西瓜[P3787洛谷]
题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有根树,琪露诺想要把它们冷冻起来慢慢吃. 这些西瓜蔓具有神奇的性质,可以将经过它的 ...
- [洛谷 P3787] 冰精冻西瓜
题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有根树,琪露诺想要把它们冷冻起来慢慢吃. 这些西瓜蔓具有神奇的性质,可以将经过它的 ...
- [luogu P3786]萃香抱西瓜 [spfa][状态压缩]
题目背景 伊吹萃香(Ibuki Suika)正在魔法之森漫步,突然,许多西瓜(Suika)从四周飞来,划出了绚丽的轨迹.虽然阵势有点恐怖,但她还是决定抱走一些西瓜. 题目描述 萃香所处的环境被简化为一 ...
- 【Luogu】P3786萃香抱西瓜(状压DP)
题目链接 水题,数据范围提示得太明显了吧,不用动脑子都能知道是状压. 不过还是有坑(当然更可能是我脑子有坑) f[i][j][k][l]表示当前是第i秒,萃香在(j,k),已经抱到的西瓜状态是l的最少 ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
随机推荐
- httpd安装与配置(编译安装)
httpd简介 httpd是Apache超文本传输协议(HTTP)服务器的主程序.被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池. 通常,httpd不应该被直接调用,而应该在类 ...
- EntityFramWork(3 code First 约定)
Code First 约定 借助 Code First,可通过使用 C# 或 Visual Basic .NET 类来描述模型.模型的基本形状可通过约定来检测.约定是规则集,用于在使用 Code ...
- Hibernate 基础入门
概述: JDBC:将java和数据库连接的驱动程序加载到项目中,在代码里面,注册驱动,创建链接,创建satement对象,发送并执行sql之类,关闭连接. hibernate :数据持久化一个框架,对 ...
- 实战C++对象模型之成员函数调用
先说结论:C++的类成员函数和C函数实质是一样的,只是C++类成员函数多了隐藏参数this. 通过本文的演示,可以看见这背后的一切,完全可C函数方式调用C++类普通成员函数和C++类虚拟成员函数. 为 ...
- 【python-HTMLTestRunner】生成HTMLTestRunner报告报错ERROR 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
[python-HTMLTestRunner]生成HTMLTestRunner报告报错:ERROR 'ascii' codec can't decode byte 0xe5 in position 0 ...
- 安装Intellij IDEA(ideaIU-2017.2.3)并完成Intellij IDEA的简单配置
一.Intellij IDEA的简介 Intellij IDEA是java语言的集成开发环境,与Eclipse相比,它的功能更多.更强大.更智能,Eclipse更适合刚学习java语言的初学者,它操作 ...
- Java并发控制机制
在一般性开发中,笔者经常看到很多同学在对待java并发开发模型中只会使用一些基础的方法.比如volatile,synchronized.像Lock和atomic这类高级并发包很多人并不经常使用.我想大 ...
- SSD磁盘测试不达标排查
最近购买了一块4T的Inter_SSD_D3-4510硬盘安装在了一台DELL PowerEdge R640服务器,经过测试发现磁盘和产品手册上描述的性能相差过大,相当于产品手册性能的1/2,一下是 ...
- SDWebImage之SDWebImageDownloader
SDWebImageDownloader完成了对网络图片的异步下载工作,准确说这个类是一个文件下载的工具类,真正的网络请求是在继承于NSOperation的SDWebImageDownloaderOp ...
- Rabbit RPC 代码阅读(一)
前言 因为想对RPC内部的机制作一个了解,特作以下阅读代码日志,以备忘. RPC介绍 Rabbit RPC 原理可以用3点概括: 1.服务端启动并且向注册中心发送服务信息,注册中心收到后会定时监控服务 ...