Wannafly Camp 2020 Day 2F 采蘑菇的克拉莉丝 - 树链剖分

如果暴力维护,每次询问时需要对所有孩子做计算
考虑通过树剖来平衡修改与询问的时间,询问时计算重链和父树,轻链的贡献预先维护好,修改时则需要修改可能影响的轻链贡献,因为某个点到根的路径上轻重交替只有 \(O(\log n)\) 个,所以只需要修改这么多次,于是复杂度有保证,树状数组维护子树即可
我真是个憨憨,打错树剖调一晚,地上蛙血一大摊
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6+5;
int ar[N]; // index: 1 ~ N
int lowbit(int t) { return t & (-t); }
void add(int i, int v) {
	for (; i < N; ar[i] += v, i += lowbit(i));
}
void add(int i, int j, int v) {
    add (j+1, -v);
    add (i, v);
}
int sum(int i) {
	int s = 0;
	for (; i > 0; s += ar[i], i -= lowbit(i));
	return s;
}
vector <pair<int,int> > g[N];
int n,m,t1,t2,t3,pos;
int fa[N],siz[N],f[N],cnt[N],wson[N],len[N],dfn[N],top[N],ind,tot;
void dfs1(int p) {
    siz[p]=1;
    for(pair<int,int> pr:g[p]) {
        int q=pr.first, w=pr.second;
        if(q==fa[p]) continue;
        fa[q]=p;
        len[q]=w;
        dfs1(q);
        siz[p]+=siz[q];
        if(siz[q]>siz[wson[p]]) wson[p]=q;
    }
}
void dfs2(int p) {
    dfn[p]=++ind;
    if(wson[p]) {
        top[wson[p]]=top[p];
        dfs2(wson[p]);
    }
    for(pair<int,int> pr:g[p]) {
        int q=pr.first, w=pr.second;
        if(q==fa[p]) continue;
        if(q==wson[p]) continue;
        top[q]=q;
        dfs2(q);
    }
}
void modify(int v,int x) {
    cnt[v]+=x;
    //v=fa[v];
    while(v) {
        int t=top[v];
        add(dfn[t],dfn[v],x);
        f[fa[t]]+=x*len[t];
        v=fa[t];
    }
    f[0]=0;
}
int query(int p) {
    int ans=0;
    ans+=sum(dfn[wson[p]])*len[wson[p]];
    ans+=f[p];
    ans+=len[p]*(tot-sum(dfn[p]));
    //cout<<sum(dfn[wson[p]])<<"*"<<len[wson[p]]<<" + "<<
    //f[p]<<" + "<<len[p]<<"*"<<(tot-sum(dfn[p]))<<" = "<<ans<<endl;
    return ans;
}
signed main() {
    scanf("%lld",&n);
    for(int i=1;i<n;i++) {
        scanf("%lld%lld%lld",&t1,&t2,&t3);
        g[t1].push_back(make_pair(t2,t3));
        g[t2].push_back(make_pair(t1,t3));
    }
    dfs1(1);
    top[1]=1;
    dfs2(1);
    pos=1;
    scanf("%lld",&m);
    for(int i=1;i<=m;i++) {
        scanf("%lld%lld",&t1,&t2);
        if(t1==1) scanf("%lld",&t3), tot+=t3;
        if(t1==1) modify(t2,t3);
        else pos=t2;
        printf("%lld\n",query(pos));
    }
}
												
											Wannafly Camp 2020 Day 2F 采蘑菇的克拉莉丝 - 树链剖分的更多相关文章
- F	采蘑菇的克拉莉丝
		
这是一道树链剖分的题目: 很容易想到,我们在树剖后,对于操作1,直接单点修改: 对于答案查询,我们直接的时候,我们假设查询的点是3,那么我们在查询的时候可分为两部分: 第一部分:查找出除3这颗子树以外 ...
 - Wannafly Winter Camp 2020 Day 5C Self-Adjusting Segment Tree - 区间dp,线段树
		
给定 \(m\) 个询问,每个询问是一个区间 \([l,r]\),你需要通过自由地设定每个节点的 \(mid\),设计一种"自适应线段树",使得在这个线段树上跑这 \(m\) 个区 ...
 - Wannafly Camp 2020 Day 3I N门问题 - 概率论,扩展中国剩余定理
		
有一个猜奖者和一个主持人,一共有 \(n\) 扇门,只有一扇门后面有奖,主持人事先知道哪扇门后有奖,而猜奖者不知道.每一轮,猜奖者选择它认为的有奖概率最大(如果有多个最大,随机选一个)的一扇门,主持人 ...
 - Wannafly Camp 2020 Day 3F 社团管理 - 决策单调性dp,整体二分
		
有 \(n\) 个数构成的序列 \({a_i}\),要将它划分为 \(k\) 段,定义每一段的权值为这段中 \((i,j) \ s.t. \ i<j,\ a_i=a_j\) 的个数,求一种划分方 ...
 - Wannafly Camp 2020 Day 3D 求和 - 莫比乌斯反演,整除分块,STL,杜教筛
		
杜教筛求 \(\phi(n)\), \[ S(n)=n(n+1)/2-\sum_{d=2}^n S(\frac{n}{d}) \] 答案为 \[ \sum_{d=1}^n \phi(d) h(\fra ...
 - Wannafly Camp 2020 Day 2B 萨博的方程式 - 数位dp
		
给定 \(n\) 个数 \(m_i\),求 \((x_1,x_2,...,x_n)\) 的个数,使得 \(x_1 \ xor\ x_2\ xor\ ...\ xor\ x_n = k\),且 \(0 ...
 - Wannafly Camp 2020 Day 2D 卡拉巴什的字符串 - 后缀自动机
		
动态维护任意两个后缀的lcp集合的mex,支持在串末尾追加字符. Solution 考虑在 SAM 上求两个后缀的 LCP 的过程,无非就是找它们在 fail 树上的 LCA,那么 LCP 长度就是这 ...
 - Wannafly Camp 2020 Day 1D 生成树 - 矩阵树定理,高斯消元
		
给出两幅 \(n(\leq 400)\) 个点的无向图 \(G_1 ,G_2\),对于 \(G_1\) 的每一颗生成树,它的权值定义为有多少条边在 \(G_2\) 中出现.求 \(G_1\) 所有生成 ...
 - Wannafly Camp 2020 Day 2I 堡堡的宝藏 - 费用流
		
感谢这道题告诉我KM求的是 完备 最大权匹配 :( #include <bits/stdc++.h> using namespace std; #define reset(x) memse ...
 
随机推荐
- Spring Boot从入门到精通(一)搭建第一个Spring Boot程序
			
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过 ...
 - js对象模型1
 - 阿里妈妈的iconfont的引用问题
			
一.先进官网 我们看到了上面的这些图标,是不是很心动,阿里妈妈就是给力,给马老师点赞,但是问题来了我们怎么去使用呢. 二.点击图标 嘿嘿,上面的操作步骤我就不多说了吧,我相信大家都会做的,接下来我们就 ...
 - cf960F
			
输入给出m条边,要求找到一条最长的路径满足边按照输入的顺序出现并且权值严格递增 两种方法:第一种利用单调队列性质 第二种利用数据结构优化 #include<bits/stdc++.h> # ...
 - vue_day01
			
Vue_day01 1. 认识vue 1.1 什么是vue (1)Vue是构建界面的渐进式的js框架 (2)只关注视图层, 采用自底向上增量开发的设计. (3)Vue 的目标是通过尽可能简单的 API ...
 - MATLAB实例:二元高斯分布图
			
MATLAB实例:二元高斯分布图 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. MATLAB程序 %% demo Multivariate No ...
 - [PKUWC2018]Minimax [dp,线段树合并]
			
好妙的一个题- 我们设 \(f_{i,j}\) 为 \(i\) 节点出现 \(j\) 的概率 设 \(l = ch[i][0] , r = ch[i][1]\) 即左儿子右儿子 设 \(m\) 为叶子 ...
 - 数字孪生 VS 平行系统
			
数字孪生和平行系统作为新兴技术,在解决当今人工智能邻域面临的信息量大,干扰信息不确定因素多,与人的参与沟通更加紧密,人机互动更加重视,为了使人们有更好的体验人工智能带来的便利,急需推动信息物理社会的高 ...
 - React函数式组件使用Ref
			
目录: 简介 useRef forwardRef useImperativeHandle 回调Ref 简介 大家都知道React中的ref属性可以帮助我们获取子组件的实例或者Dom对象,进而对子组件进 ...
 - VSCode添加git bash作为默认终端
			
VSC添加git bash作为默认终端的settings.json添加 { "terminal.integrated.shell.windows": "D:\\Progr ...