题目链接: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. Django项目:CRM(客户关系管理系统)--10--04PerfectCRM实现King_admin注册功能02

    from django import conf #配置文件print("dj conf:",conf) #配置文件print("dj conf:",conf.s ...

  2. web前端学习(三)css学习笔记部分(8)-- SVN的介绍和应用、CSS动画效果、CSS3布局属性全接触

    15.SVN的介绍和应用 15.1.SVN的介绍和应用课程概要 将代码进行集中管理,有版本号的进行迭代,方便集体工作的build流程 15.2.SVN的介绍 SVN是Subversion的简称,是一个 ...

  3. DirectX11笔记(七)--Direct3D渲染3--INDICES AND INDEX BUFFERS

    原文:DirectX11笔记(七)--Direct3D渲染3--INDICES AND INDEX BUFFERS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  4. vue-cli3.0 资源加载的优化方案

    20180829 更新 今天反复试了,不用区分 测试环境还是 生产环境,统一都用 cdn 就可以了 背景 之前自己搭建了一个 vue + tp5.1 的后台项目(https://segmentfaul ...

  5. request与response的乱码问题的总结及解决方法

    一. response的乱码问题: 1,使用   字节流  向页面输出中文: 不一定会出现乱码,因为中文字节数组默认是GBK,如果浏览器打开的默认编码也是GBK,就不会出现乱码,否则会乱码. 解决办法 ...

  6. word之图表目录中点号位置提升3磅

  7. LintCode_111 爬楼梯

    题目 假设你正在爬楼梯,需要n步你才能到达顶部.但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部? 比如n=3,中不同的方法 返回 3 1 2 3 5 8 13... step[2] = ...

  8. nginx与apache

    参考链接:https://www.cnblogs.com/changning0822/p/7844004.html

  9. PHPCMS快速建站系列之邮箱验证

    1. 登录163邮箱,->设置,开启POP3服务->把SMTP服务器地址复制到PHPCMS后台. 2.开启客户端授权密码 3.填写相关信息,.可以在测试邮箱填入邮箱地址测试

  10. 前端规范2-CSS规范

    CSS规范 缩进 使用Tab缩进(相当于四个空格) 选择器与{之间必须包含空格,参1 属性名和之后的:不允许包含空格,:与属性值之间必须包含空格.      例 列表性属性值在单行时,后必须跟一个空格 ...