WZJ的数据结构(负三十)
难度级别:D; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

给你一棵N个点的无根树,点和边上均有权值。请你设计一个数据结构,回答M次操作。

1 x v:对于树上的每一个节点y,如果将x、y在树上的距离记为d,那么将y节点的权值加上d*v。

2 x:询问节点x的权值。

输入
第一行为一个正整数N。
第二行到第N行每行三个正整数ui,vi,wi。表示一条树边从ui到vi,距离为wi。
第N+1行为一个正整数M。
最后M行每行三个或两个正整数,格式见题面。
输出
对于每个询问操作,输出答案。
输入示例
10
1 2 2
1 3 1
1 4 3
1 5 2
4 6 2
4 7 1
6 8 1
7 9 2
7 10 1
9
1 3 1
1 10 1
2 1
2 4
2 5
1 5 1
1 8 1
2 2
2 9
输出示例
6
6
10
22
24
其他说明
对于30%的数据:1<=N,M<=1000
另有50%的数据:1<=N,M<=100000,保证修改操作均在询问操作之前。
对于100%的数据:1<=N,M<=100000,1<=x<=N,1<=v,wi<=1000

将问题转化为计算贡献,那么修改对应更改点权,查询对应带权距离之和,动态树分治就可以了。

用sz表示子树中权值之和,sumv表示子树所有点到其带权距离之和,sumv2表示子树所有点到其父亲带权距离之和。

两个操作均是O(logn)

#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
typedef long long ll;
const int maxn=;
int n,q,first[maxn],next[maxn<<],to[maxn<<],dis[maxn<<],e;
void AddEdge(int w,int v,int u) {
to[++e]=v;dis[e]=w;next[e]=first[u];first[u]=e;
to[++e]=u;dis[e]=w;next[e]=first[v];first[v]=e;
}
int mn[maxn<<][],Log[maxn<<],dep[maxn],pos[maxn],cnt;
void dfs(int x,int fa) {
mn[++cnt][]=dep[x];pos[x]=cnt;
ren if(to[i]!=fa) dep[to[i]]=dep[x]+dis[i],dfs(to[i],x),mn[++cnt][]=dep[x];
}
void pre() {
Log[]=-;
rep(i,,cnt) Log[i]=Log[i>>]+;
for(int j=;(<<j)<=cnt;j++)
for(int i=;i+(<<j)-<=cnt;i++)
mn[i][j]=min(mn[i][j-],mn[i+(<<j-)][j-]);
}
int dist(int x,int y) {
int ans=dep[x]+dep[y];
x=pos[x];y=pos[y];if(x>y) swap(x,y);
int k=Log[y-x+];
return ans-*min(mn[x][k],mn[y-(<<k)+][k]);
}
int vis[maxn],f[maxn],s[maxn],size,root;
void getroot(int x,int fa) {
s[x]=;int maxs=;
ren if(to[i]!=fa&&!vis[to[i]]) {
getroot(to[i],x);
s[x]+=s[to[i]];
maxs=max(maxs,s[to[i]]);
}
f[x]=max(size-s[x],maxs);
if(f[x]<f[root]) root=x;
}
int fa[maxn];
void solve(int x) {
vis[x]=;
ren if(!vis[to[i]]) {
size=f[]=s[to[i]];getroot(to[i],root=);
fa[root]=x;solve(root);
}
}
ll sz[maxn],sumv[maxn],sumv2[maxn];
void update(int v,int x) {
sz[x]+=v;
for(int i=x;fa[i];i=fa[i]) {
int D=dist(x,fa[i]);
sz[fa[i]]+=v;sumv[fa[i]]+=(ll)D*v;sumv2[i]+=(ll)D*v;
}
}
ll query(int x) {
ll ans=sumv[x];
for(int i=x;fa[i];i=fa[i]) {
int D=dist(x,fa[i]);
ans+=(sumv[fa[i]]-sumv2[i])+(sz[fa[i]]-sz[i])*D;
}
return ans;
}
int main() {
n=read();
rep(i,,n) AddEdge(read(),read(),read());
dfs(,);pre();
size=f[]=n;getroot(,);solve(root);
q=read();
while(q--)
if(read()==) printf("%lld\n",query(read()));
else update(read(),read());
return ;
}

COJ970 WZJ的数据结构(负三十)的更多相关文章

  1. COJ966 WZJ的数据结构(负三十四)

    WZJ的数据结构(负三十四) 难度级别:C: 运行时间限制:20000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给一棵n个节点的树,请对于形如"u  ...

  2. COJ968 WZJ的数据结构(负三十二)

    WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...

  3. COJ 0970 WZJ的数据结构(负三十)树分治

    WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...

  4. [COJ0968]WZJ的数据结构(负三十二)

    [COJ0968]WZJ的数据结构(负三十二) 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着.请你设计一个数据结构,回答M次操作. 1 x:将节点x上的灯拉一次,即亮变 ...

  5. [COJ0970]WZJ的数据结构(负三十)

    [COJ0970]WZJ的数据结构(负三十) 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计一个数据结构,回答M次操作. 1 x v:对于树上的每一个节点y,如果将x.y在树上的距离记为 ...

  6. COJ 1003 WZJ的数据结构(三)ST表

    WZJ的数据结构(三) 难度级别:B: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为N的 ...

  7. 数据结构(三十四)最短路径(Dijkstra、Floyd)

    一.最短路径的定义 在网图和非网图中,最短路径的含义是不同的.由于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径:而对于网图来说,最短路径是指两顶点之间经过的边上权值之 ...

  8. 数据结构(三十二)图的遍历(DFS、BFS)

    图的遍历和树的遍历类似.图的遍历是指从图中的某个顶点出发,对图中的所有顶点访问且仅访问一次的过程.通常有两种遍历次序方案:深度优先遍历和广度优先遍历. 一.深度优先遍历 深度优先遍历(Depth_Fi ...

  9. COJ986 WZJ的数据结构(负十四)

    WZJ的数据结构(负十四) 难度级别:D: 运行时间限制:6000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小 ...

随机推荐

  1. CheckBoxList1复选框

    循环绑定数据的两个方法: List<string> LIColl = new List<string>(); protected void Page_Load(object s ...

  2. Ubuntu进不去,显示error:unknown filesystem (最简单解决方案总结)

    error filesysterm:文件系统错误 grub rescue:是让你拯救grub,就是你的grub坏了,引导程序坏了 要安装盘?要重装?No…… 只要几行命令就ok了 是的,这是我昨天亲自 ...

  3. opencv学习笔记(一)IplImage, CvMat, Mat 的关系

    opencv学习笔记(一)IplImage, CvMat, Mat 的关系 opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,M ...

  4. mysql中的sql总结

    >>>>>增加字段 ALTER TABLE pj_account ADD COLUMN test INT(11)   NOT NULL DEFAULT 1   COMME ...

  5. icon上添加数字提醒

    使用viewbadger包: package com.jingle.vierbagerstudy; import android.app.Activity; import android.os.Bun ...

  6. 安卓向服务器发送List数据

    第一步: 首先写一个自定义的JavaBean,以UserInfo.java为例,需要实现对象序列化的接口,因为之后输出流对象需要实现输出可序列化的对象.不这样的话,后续时发送时会报异常 package ...

  7. MySQL常用的自带函数

    MySQL自带函数十分丰富,合理使用可以减少很多编码工作. >>数学函数 数学函数主要用于处理数字,包括整型.浮点数等.数学函数包括绝对值函数.正弦函数.余弦函数.获取随机数的函数等.AB ...

  8. JS中使用EL表达式

    转自:http://blog.csdn.net/monkeyking1987/article/details/17146951 分两种情况 1. JS代码在JSP页面中, 这可以直接使用EL表达式. ...

  9. Android学习 之 startActivityForResult 和 onActivityResult

    startActivityForResult 和 onActivityResult() 作用:主要用于 主Activity向调用的 子Activity 获得数据. 使用方法:在 主Activity写 ...

  10. Introduction to Computer Networks(网络架构与七层参考模式)

    Network Connectivity 1. Important terminologies 1) Link 设备连接的连线.Link本身既可以是有线的,也可以是无线的. 2) Node 设备.电脑 ...