题解

这道题维护方法比较简单,也有点奇妙

我们可以很容易求出经过所有点的路径条数,和初始时分子的大小

然后单点修改的时候,相当于给当前点\(v\)加上\(delta * (siz[v] - 1)\)

\(v\)到根的路径上每个祖先都要加上设\(t\)为\(k\)在路径上的儿子,\(delta * (siz[k] - siz[t])\)

如果想把这种操作快速修改的话,我们把这个操作放到重链上,这样只有重链顶端的父亲需要特殊处理,剩下的值都已经计算好了,用一个标记在线段树上维护就好

然后考虑区间加,对于修改的这个\(v\),我们相当于加上\(delta * 2 * path[v]\),而v所有的儿子以及后代都是一样的操作,所以我们维护第二个标记用来乘上每个节点的\(path[u] * 2\)

对于\(v\)的祖先,就相当于单点修改增加了\(siz[v] * delta\)了

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
//#define ivorysi
#define MAXN 300005
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
struct node {
int to,next;
}E[MAXN * 2];
int N,head[MAXN],sumE,M;
int siz[MAXN],dfn[MAXN],son[MAXN],idx,top[MAXN],fa[MAXN],dep[MAXN];
int64 path[MAXN],tag[MAXN],val[MAXN],w[MAXN],sum[MAXN];
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
struct segment_tree {
struct node {
int L,R;
pair<int64,int64> d;
}tr[MAXN * 4];
pair<int64,int64> Merge(pair<int64,int64> a,pair<int64,int64> b) {
return mp(a.fi + b.fi,a.se + b.se);
}
void push_down(int u) {
tr[u << 1].d = Merge(tr[u].d,tr[u << 1].d);
tr[u << 1 | 1].d = Merge(tr[u].d,tr[u << 1 | 1].d);
tr[u].d = mp(0,0);
}
void build(int u,int L,int R) {
tr[u].L = L;tr[u].R = R;
tr[u].d = mp(0,0);
if(L == R) return;
int mid = (L + R) >> 1;
build(u << 1,L,mid);
build(u << 1 | 1,mid + 1,R);
}
void Add(int u,int l,int r,pair<int64,int64> d) {
if(tr[u].L == l && tr[u].R == r) {
tr[u].d = Merge(d,tr[u].d);
return;
}
push_down(u);
int mid = (tr[u].L + tr[u].R) >> 1;
if(r <= mid) Add(u << 1,l,r,d);
else if(l > mid) Add(u << 1 | 1,l,r,d);
else {Add(u << 1,l,mid,d);Add(u << 1 | 1,mid + 1,r,d);}
}
pair<int64,int64> Query(int u,int pos) {
if(tr[u].L == tr[u].R) return tr[u].d;
push_down(u);
int mid = (tr[u].L + tr[u].R) >> 1;
if(pos <= mid) return Query(u << 1,pos);
else return Query(u << 1 | 1,pos);
}
}Tr; void Add_Path(int u,int64 v) {
while(u) {
int t = top[u];
if(dfn[t] <= dfn[u] - 1) Tr.Add(1,dfn[t],dfn[u] - 1,mp(v,0));
if(fa[t]) val[fa[t]] += (siz[fa[t]] - siz[t]) * v;
u = fa[t];
}
} void dfs1(int u) {
siz[u] = 1;
dep[u] = dep[fa[u]] + 1;
sum[u] = w[u];
dfn[u] = ++idx;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa[u]) {
fa[v] = u;
dfs1(v);
sum[u] += sum[v];
path[u] += siz[u] * siz[v];
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
}
val[u] += w[u] * (siz[u] - 1);
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa[u]) {
val[u] += sum[v] * (siz[u] - siz[v]);
}
}
tag[u] = siz[u] - siz[son[u]];
}
void dfs2(int u) {
if(!top[u]) {top[u] = u;}
if(son[u]) {
top[son[u]] = top[u];
dfs2(son[u]);
}
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa[u] && v != son[u]) {
dfs2(v);
}
}
}
void Init() {
read(N);read(M);
int p;
for(int i = 2 ; i <= N ; ++i) {
read(p);
add(p,i);add(i,p);
}
for(int i = 1 ; i <= N ; ++i) read(w[i]);
dfs1(1);dfs2(1);
Tr.build(1,1,N);
} void Solve() {
char op[5];
int u;int64 v;
while(M--) {
scanf("%s",op + 1);
if(op[1] == 'S') {
read(u);read(v);
val[u] += (siz[u] - 1) * v;
Add_Path(u,v);
}
else if(op[1] == 'M'){
read(u);read(v);
Tr.Add(1,dfn[u],dfn[u] + siz[u] - 1,mp(0,v));
if(fa[u]) val[fa[u]] += siz[u] * v * (siz[fa[u]] - siz[u]);
Add_Path(fa[u],siz[u] * v);
}
else {
read(u);
pair<int64,int64> res = Tr.Query(1,dfn[u]);
int64 up = res.fi * tag[u] + res.se * 2 * path[u] + val[u];
int64 down = path[u];
printf("%.6lf\n",(db)up / down);
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
return 0;
}

【BZOJ】3683: Falsita的更多相关文章

  1. 【BZOJ】3052: [wc2013]糖果公园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...

  2. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  3. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

  4. 【BZOJ】1013: [JSOI2008]球形空间产生器sphere

    [BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...

  5. 【BZOJ】1002:轮状病毒(基尔霍夫矩阵【附公式推导】或打表)

    Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...

  6. 【BZOJ】【3083】遥远的国度

    树链剖分/dfs序 其实过了[BZOJ][4034][HAOI2015]T2以后就好搞了…… 链修改+子树查询+换根 其实静态树的换根直接树链剖分就可以搞了…… 因为其实只有一样变了:子树 如果roo ...

  7. 【BZOJ】【2434】【NOI2011】阿狸的打字机

    AC自动机+DFS序+BIT 好题啊……orz PoPoQQQ 大爷 一道相似的题目:[BZOJ][3172][TJOI2013]单词 那道题也是在fail树上数有多少个点,只不过这题是在x的fail ...

  8. 【BZOJ】【2738】&【Tsinsen】【A1333】矩阵乘法

    整体二分+树状数组 过了[BZOJ][2527][POI2011]Meteors以后这题就没那么难啦~ 关键是[从小到大]依次插入数字,然后整体二分每个查询的第k大是在第几次插入中被插入的……嗯大概就 ...

  9. 【BZOJ】【3170】【TJOI2103】松鼠聚会

    切比雪夫距离+曼哈顿距离 题解:http://www.cnblogs.com/zyfzyf/p/4105456.html 其实应该先做这题再做[BZOJ][3210]花神的浇花集会的吧…… 我们发现d ...

随机推荐

  1. 【题解】 [HNOI2015]落忆枫音 (拓扑排序+dp+容斥原理)

    原题戳我 Solution: (部分复制Navi_Aswon博客) 解释博客中的两个小地方: \[\sum_{\left(S是G中y→x的一条路径的点集\right))}\prod_{2≤j≤n,(j ...

  2. 从web启动winform程序

    最近有个客户提出想从网站上启动一个客户端的程序,研究了下,实现方法如下: 1. 注入注册表 try                {                    string appPath ...

  3. 自动化运维工之Ansible(1)

    1.1 ansible简介 1.1.1 .Ansible软件介绍: Ansible提供一种最简单的方式用于发布.管理和编排计算机系统的工具,可在数分钟内搞定.Ansible由Python语言开发, 默 ...

  4. 面试题:get和post的本质区别

    前言:相信小伙伴们面试时候一定都遇到过这个问题,即使没有遇到过,至少也听说过,网上资料一大片,大概每个人都能说出来一些.但是总感觉面试装逼不成功,所以就翻阅了部分资料,进一步整理了下. 一般当我们提到 ...

  5. java lock锁住特定对象

    由于lock没有锁住特定对象的概念,该如何做到像synchronized同步块一样的效果呢? 答案:为每一个需要加锁的对像分配一把锁. 示例: List<User> users = new ...

  6. python deamon(守护)线程的作用

    stackoverflow 上的解释 某些线程执行后台任务,例如发送keepalive数据包,或执行定期垃圾收集,或任何.这些仅在主程序运行时有用,并且一旦其他非守护程序线程退出就可以将其关闭. 没有 ...

  7. CSS 笔记(一)

    学习了张鑫旭大神的浮动教程,记一下笔记. 浮动最开始是为了文字环绕图片效果. 浮动会破坏父元素的包裹. 清除浮动:在父元素加上clearfix(after不兼容ie6 7,zoom为ie6 7下方法) ...

  8. android中实现在ImageView上随意画线涂鸦

    我实现的思路: 1.继承ImageView类 2.重写onTouchEvent方法,在ACTION_MOVE(即移动时),记录下所经过的点坐标,在ACTION_UP时(即手指离开时,这时一条线已经画完 ...

  9. WIN10文件无法自动刷新问题解决方法

    Window10系统有时候会遇到以下类似的问题 1.文件删除后,图标还在,无法自动刷新屏幕,按F5或右键菜单刷新后才消失 2.文件粘贴后,不显示,刷新后才显示 3.回收站清理后,文件图标仍显示有垃圾 ...

  10. Workflow规则收藏

    豆瓣电影  查看电影评分等详细信息 查看图片EXIF 图铃机器人 快递查询 翻译 手机号码归属地 音乐视频下载 获取附近的免费WIFI