题目大意:

有一棵 n n n节点的树,根为 1" role="presentation">111 号节点。每个节点有两个权值 ki,ti k i , t i k_i, t_i​​,初始值均为 0 0 0。
给出三种操作:
Add(x,d)" role="presentation">Add(x,d)Add(x,d)\mathrm{Add}( x , d )操作:将 x x x到根的路径上所有点的ki←ki+d" role="presentation">ki←ki+dki←ki+dk_i\leftarrow k_i + d
Mul(x,d) M u l ( x , d ) \mathrm{Mul}( x , d )操作:将 x x x到根的路径上所有点的ti←ti+d×ki" role="presentation">ti←ti+d×kiti←ti+d×kit_i\leftarrow t_i + d \times k_i
Query(x) Q u e r y ( x ) \mathrm{Query}( x )操作:询问点 x x x的权值tx" role="presentation">txtxt_x

思路:

线段树好题。
首先把树上的操作通过树链剖分就转变为了序列上面的操作了。然后考虑怎么在序列上面维护每一个点的答案。
由于修改是区间修改,所以在线段树上的操作不可以及时更新,需要打标记,并且一个标记暂时是独立表示一个状态的,因此我们的标记要满足可以与之前的点快速合并。
将操作转化一下以便于理解,1操作可以看不断地增加一个矩形某条边的高,2操作可以看成在前面所有的高的基础下矩形的宽又增加 d d <script type="math/tex" id="MathJax-Element-399">d</script>个单位。
这样以后对于两个不同的已知状态的矩形,就可以通过记录每个矩形目前的高和宽以及通过操作得到的面积快速pushdown了。具体操作看pushdown里面的代码会便于理解。

/*========================
Author : ylsoi
Problem : loj6208
Algorithm : Segment Tree
Time : 2018.8.1
========================*/
#include<bits/stdc++.h>#define REP(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;using namespace std;void File(){freopen("loj6208.in","r",stdin);freopen("loj6208.out","w",stdout);
}template<typename T>void read(T &_){T __=0,mul=1; char ch=getchar();while(!isdigit(ch)){if(ch=='-')mul=-1;ch=getchar();}while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();_=__*mul;
}const int maxn=1e5+10;
int n,m;
int cnte=1,beg[maxn],las[maxn<<1],to[maxn<<1];
int dep[maxn],son[maxn],fa[maxn],siz[maxn],top[maxn],dfn[maxn],cnt_dfn;void add(int u,int v){las[++cnte]=beg[u]; beg[u]=cnte; to[cnte]=v;las[++cnte]=beg[v]; beg[v]=cnte; to[cnte]=u;
}void dfs1(int u,int f){dep[u]=dep[f]+1; fa[u]=f; siz[u]=1;for(int i=beg[u];i;i=las[i]){if(to[i]==f)continue;dfs1(to[i],u);siz[u]+=siz[to[i]];if(siz[to[i]]>siz[son[u]])son[u]=to[i];}
}void dfs2(int u,int t){top[u]=t; dfn[u]=++cnt_dfn;if(son[u])dfs2(son[u],t);for(int i=beg[u];i;i=las[i]){if(to[i]==son[u] || to[i]==fa[u])continue;dfs2(to[i],to[i]);}
}struct Segment_Tree{
#define mid ((l+r)>>1)
#define lc rt<<1
#define rc rt<<1|1
#define lson lc,l,mid
#define rson rc,mid+1,rll a[maxn<<2],b[maxn<<2],c[maxn<<2];void pushdown(int rt){c[lc]=c[lc]+c[rt]+a[lc]*b[rt]; a[lc]+=a[rt]; b[lc]+=b[rt];c[rc]=c[rc]+c[rt]+a[rc]*b[rt]; a[rc]+=a[rt]; b[rc]+=b[rt];c[rt]=a[rt]=b[rt]=0;}void update(int rt,int l,int r,int L,int R,bool ty,ll x){if(L<=l && r<=R){if(ty==0)a[rt]+=x;else b[rt]+=x,c[rt]+=a[rt]*x;}else{pushdown(rt);if(L<=mid)update(lson,L,R,ty,x);if(R>=mid+1)update(rson,L,R,ty,x);}}ll query(int rt,int l,int r,int pos){if(l==r)return c[rt];pushdown(rt);if(pos<=mid)return query(lson,pos);else return query(rson,pos);}
}T;void modify(bool ty,int u,ll x){while(u){T.update(1,1,n,dfn[top[u]],dfn[u],ty,x);u=fa[top[u]];}
}int main(){File();read(n);int ty,u,v;REP(i,1,n-1)read(u),read(v),add(u,v);dfs1(1,0); dfs2(1,1);read(m);REP(i,1,m){read(ty);if(ty==1 || ty==2){read(u); read(v);modify(ty-1,u,v);}else{read(u);printf("%lld\n",T.query(1,1,n,dfn[u]));}}return 0;
}

[loj6208]树上询问——线段树相关推荐

  1. 洛谷 - P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并(树上差分+线段树合并)

    题目链接:点击查看 题目大意:给出一棵树,再给出 m 次操作,每次操作会选择两个点 ( x , y ) ,使得这条路径上的所有点的种类 z 加一,最后问每个点的哪个种类出现的频率最高,若多个种类出现频 ...

  2. [Vani有约会]雨天的尾巴 (线段树合并)

    题目链接 Solution 树上差分+线段树合并. 在每个节点上维护一棵权值线段树. 然后如果需要修改 \(x,y\) 两点,则在 \(x\) 处和 \(y\) 处分别加上 \(1\) 的权值. 然后 ...

  3. 图中异色点对最短距离(最小生成树+线段树)

    problem 给定一个 nnn 个点,mmm 条边的无向连通图,图有边权,每个点有一个颜色. 有 qqq 次操作,每次操作可更改某一个点颜色. 求每次操作后图中不同颜色点之间的最短距离. 若图中点颜 ...

  4. YbtOJ#532-往事之树【广义SAM,线段树合并】

    正题 题目链接:https://www.ybtoj.com.cn/problem/532 题目大意 给出nnn个点的一个TrieTrieTrie树,定义SxS_xSx​表示节点xxx代表的字符串 求m ...

  5. BZOJ5419[Noi2018]情报中心——线段树合并+虚树+树形DP

    题目链接: [NOI2018]情报中心 题目大意:给出一棵n个节点的树,边有非负边权,并给出m条链,对于每条链有一个代价,要求选出两条有公共边的链使两条链的并的边权和-两条链的代价和最大. 花了一天的 ...

  6. 【线段树】【模板】讲解 + 例题1 HDU - 1754 I Hate It (点修改分数)+ 例题二 POJ - 3468 A Simple Problem with Integers(区间加值)

    [线段树][模板]讲解 + 例题1 HDU - 1754 I Hate It (点修改分数)+ 例题二 POJ - 3468 A Simple Problem with Integers(区间加值) ...

  7. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

  8. 【线段树合并】解题报告:luogu P4556雨天的尾巴 (树上对点差分 + 动态开点 + 线段树合并)线段树合并模板离线/在线详解

    题目链接:雨天的尾巴 本题本身是一个非常简单的一道树上差分的模板题,但是由于变态的数据范围,我们直接用数组是存不下的(本来使用一颗普通的线段树直接维护最大值即可.但是本题的空间只有128MB,直接按照 ...

  9. 2020-2021年度第二届全国大学生算法设计与编程挑战赛 (春季赛)- 天才的操作(线段树+主席树+树上倍增)

    题目链接:点击查看 题目分析:刚看到这个题目的时候,口胡了一个假算法,觉得对于每次询问的操作 [l,r][l,r][l,r] ,只需要找到指令集区间 [l,r][l,r][l,r] 内覆盖到点 kkk ...

最新文章

  1. Maven常用参数及其说明
  2. python3 多进程共享变量实现方法
  3. android,项目,一些教程
  4. show profile 分析SQL
  5. c语言while退出无限循环,请教:为什么我用while(!feof(fp))时会出现无限循环????...
  6. Pytorch 之 TSM(Time Shift Module)测试部分源码详解
  7. wordpress去掉category怎么操作让url更简洁友好
  8. leetcode -- 303. 区域和检索 - 数组不可变
  9. .NET Core开源组件:后台任务利器之Hangfire
  10. Maven入门实战笔记-11节[7-11]
  11. 获取base64编码格式的图片大小
  12. Oracle | awr报告分析
  13. cmd命令行常用指令
  14. day4 vue 学习笔记 组件 生命周期 数据共享 数组常用方法
  15. Android应用开发编译框架流程与IDE及Gradle概要
  16. java菜单栏尺寸设置_java – 如何设置JMenuItem的大小?
  17. 传送带效果实现 | Unity
  18. 深度学习总结:深层神经网络(tensorflow实战)
  19. 深入理解:scp,rsync,sftp,xsync等命令的基本使用方法,以及cmd命令窗口下进行相关的ssh命令操作
  20. 360影视php视频系统源码,全新360影视2.0完整源码 双端APP+三级分销 附视频搭建教程...

热门文章

  1. Keil5编程error: #18: expected a “)“问题解决
  2. 友情链接交换标准注意事项
  3. 如何快速获取网页源码(直接把网站的 js css html 扒下来的)
  4. 基于 phylotree.js 基因进化树可视化图谱(gene-tree)
  5. JS 获取数组元素相同的下标
  6. C++基础:面向对象编程
  7. Hadoop Failed to set permissions of path 错误处理
  8. C++ override解释
  9. 「建模学习」使用maya制作原始森林,图文详细步骤,maya教程
  10. YARN应用程序开发流程(类似于MapReduce On Yarn)本内容版权归(小象学院所有)...