题目链接:https://www.luogu.org/problem/P3313

这道题目就是树链剖分+线段树动态开点。

然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题目:

https://www.cnblogs.com/codedecision/p/11791200.html

然后你就会发现这就是树链剖分+上题的线段树处理。

然后这道题目就变得很简单。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
#define INF (1<<29)
const int maxn = 100010; int fa[maxn],
dep[maxn],
size[maxn],
son[maxn],
top[maxn],
seg[maxn], seg_cnt,
rev[maxn];
vector<int> g[maxn];
void dfs1(int u, int p) {
size[u] = 1;
for (vector<int>::iterator it = g[u].begin(); it != g[u].end(); it ++) {
int v = (*it);
if (v == p) continue;
fa[v] = u;
dep[v] = dep[u] + 1;
dfs1(v, u);
size[u] += size[v];
if (size[v] >size[son[u]]) son[u] = v;
}
}
void dfs2(int u, int tp) {
seg[u] = ++seg_cnt;
rev[seg_cnt] = u;
top[u] = tp;
if (son[u]) dfs2(son[u], tp);
for (vector<int>::iterator it = g[u].begin(); it != g[u].end(); it ++) {
int v = (*it);
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
struct Tnode {
int l, r, sumw, maxw;
Tnode *lson, *rson;
Tnode(int _l, int _r, int _sumw, int _maxw) { l = _l; r = _r; sumw = _sumw; maxw = _maxw; lson = rson = NULL; }
} *root[maxn];
int n, q, w[maxn], c[maxn];
void push_up(Tnode *rt) {
rt->sumw = rt->maxw = 0;
if (rt->lson != NULL) {
rt->sumw += rt->lson->sumw;
rt->maxw = max(rt->maxw, rt->lson->maxw);
}
if (rt->rson != NULL) {
rt->sumw += rt->rson->sumw;
rt->maxw = max(rt->maxw, rt->rson->maxw);
}
}
void update(int p, int v, Tnode *rt) {
int l = rt->l, r = rt->r, mid = (rt->l + rt->r) / 2;
if (l == r) {
rt->sumw = rt->maxw = v;
return;
}
if (p <= mid) {
if (rt->lson == NULL) rt->lson = new Tnode(l, mid, 0, 0);
update(p, v, rt->lson);
}
else {
if (rt->rson == NULL) rt->rson = new Tnode(mid+1, r, 0, 0);
update(p, v, rt->rson);
}
push_up(rt);
}
int query_sum(int L, int R, Tnode *rt) {
int l = rt->l, r = rt->r, mid = (rt->l + rt->r) / 2;
if (L <= l && r <= R) return rt->sumw;
int tmp = 0;
if (L <= mid && rt->lson != NULL) tmp += query_sum(L, R, rt->lson);
if (R > mid && rt->rson != NULL) tmp += query_sum(L, R, rt->rson);
return tmp;
}
int query_max(int L, int R, Tnode *rt) {
int l = rt->l, r = rt->r, mid = (rt->l + rt->r) / 2;
if (L <= l && r <= R) return rt->maxw;
int tmp = 0;
if (L <= mid && rt->lson != NULL) tmp = max(tmp, query_max(L, R, rt->lson));
if (R > mid && rt->rson != NULL) tmp = max(tmp, query_max(L, R, rt->rson));
return tmp;
}
void init() {
for (int i = 1; i < maxn; i ++) root[i] = new Tnode(1, n, 0, 0);
}
int ask_sum(int u, int v) {
int res = 0;
Tnode* rt = root[c[u]];
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
res += query_sum(seg[top[u]], seg[u], rt);
u = fa[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
res += query_sum(seg[v], seg[u], rt);
return res;
}
int ask_max(int u, int v) {
int res = -INF;
Tnode* rt = root[c[u]];
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
res = max(res, query_max(seg[top[u]], seg[u], rt));
u = fa[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
res = max(res, query_max(seg[v], seg[u], rt));
return res;
}
int x, y;
string op;
int main() {
cin >> n >> q;
for (int i = 1; i <= n; i ++) {
cin >> w[i] >> c[i];
}
for (int i = 1; i < n; i ++) {
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
dep[1] = fa[1] = 1;
dfs1(1, -1);
dfs2(1, 1);
init();
for (int i = 1; i <= n; i ++) {
update(seg[i], w[i], root[c[i]]);
}
while (q --) {
cin >> op >> x >> y;
if (op == "CC") {
update(seg[x], 0, root[c[x]]);
c[x] = y;
update(seg[x], w[x], root[c[x]]);
}
else if (op == "CW") {
update(seg[x], y, root[c[x]]);
w[x] = y;
}
else if (op == "QS") {
cout << ask_sum(x, y) << endl;
}
else { // QM
cout << ask_max(x, y) << endl;
}
}
return 0;
}

洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点的更多相关文章

  1. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

  2. 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树

    正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...

  3. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  4. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  5. POJ3237 Tree 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...

  6. 【CF725G】Messages on a Tree 树链剖分+线段树

    [CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...

  7. 【bzoj5210】最大连通子块和 树链剖分+线段树+可删除堆维护树形动态dp

    题目描述 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块和. 其中,一棵子树的最大连通子块和指的是:该子树 ...

  8. 【bzoj4712】洪水 树链剖分+线段树维护树形动态dp

    题目描述 给出一棵树,点有点权.多次增加某个点的点权,并在某一棵子树中询问:选出若干个节点,使得每个叶子节点到根节点的路径上至少有一个节点被选择,求选出的点的点权和的最小值. 输入 输入文件第一行包含 ...

  9. 2243: [SDOI2011]染色 树链剖分+线段树染色

    给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...

随机推荐

  1. Leetcode56. Merge Intervals合并区间

    给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 [1,3] ...

  2. FTP权限问题解析,553 Can't open that file: Permission denied

    FTP上传文件,提示553 Can't open that file: Permission denied 原因: 目录的所属组,所属用户属于root, 导致FTP无法上传, 修改组和所属用户为www ...

  3. 第十章—DOM(三)——Text类型

    文本节点由TEXT类型表示,包含纯文本内容,Text节点具有以下特征: 看看下面的代码: div元素开始和结束标签只要存在内容,就会创建一个文本节点.可以使用以下代码来访问元素的这些文本子节点: 访问 ...

  4. LintCode_173 链表插入排序

    题目 用插入排序对链表排序 样例 Given 1->3->2->0->null, return 0->1->2->3->null C++代码 ListN ...

  5. SQL —— 存储过程

    一.什么是存储过程 预先存储好的SQL程序. 保存在SQL Server中(跟视图的存储方式一样) 通过名称和参数执行. 二.存储过程的优点 执行速度更快 允许模块化程序设计 提高系统安全性 减少网络 ...

  6. 分布式--ActiveMQ 消息中间件(一) https://www.jianshu.com/p/8b9bfe865e38

    1. ActiveMQ 1). ActiveMQ ActiveMQ是Apache所提供的一个开源的消息系统,完全采用Java来实现,因此,它能很好地支持J2EE提出的JMS(Java Message ...

  7. 跟我一起学extjs5(02--建立project项目)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jfok/article/details/35569057 跟我一起学extjs5(02--建立pro ...

  8. transform的兼容性写法

    大多数浏览器都有自己的私有前缀,IE的私有前缀是 -ms- 但是大多数CSS3属性对IE低版本就不友好了,所以一般IE9+才能用上transform:rotate(7deg); -ms-transfo ...

  9. li设置多选和取消选择的样式、输入数据类型判断

    li设置多选和取消选择的样式: $('li').click(function(){ if($(this).hasClass('active')) {$(this).removeClass('activ ...

  10. Net Transport

    在调用第三方请求时,正确使用Client也不是一件非常容易的事. 下面是截取的一段描述,建议Client或Transport在整个服务期间最好是全局单例的,Transport本身会维护连接的状态,而且 ...