BZOJ 3531: [Sdoi2014]旅行 (树剖+动态开点线段树)
对于每种信仰维护一棵动态开点线段树就行了…
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
inline void read(int &num) {
char ch; int flg=1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(num=0; isdigit(ch); num=num*10+ch-'0',ch=getchar()); num*=flg;
}
const int MAXN = 100005;
const int INF = 1e9;
int n, m, cnt, tmr, fir[MAXN], fa[MAXN], dfn[MAXN], top[MAXN], sz[MAXN], son[MAXN], dep[MAXN];
struct edge { int to, nxt; }e[MAXN<<1];
inline void Add(int u, int v) {
e[cnt] = (edge){ v, fir[u] }, fir[u] = cnt++;
}
void dfs(int x) {
dep[x] = dep[fa[x]] + (sz[x]=1);
for(int v, i = fir[x]; ~i; i = e[i].nxt)
if((v=e[i].to) != fa[x]) {
fa[v] = x, dfs(v), sz[x] += sz[v];
if(sz[v] > sz[son[x]]) son[x] = v;
}
}
void dfs2(int x, int tp) {
top[x] = tp; dfn[x] = ++tmr;
if(son[x]) dfs2(son[x], tp);
for(int v, i = fir[x]; ~i; i = e[i].nxt)
if((v=e[i].to) != son[x] && v != fa[x]) dfs2(v, v);
}
namespace SegmentTree {
struct seg {
seg *ls, *rs;
int mx, sum;
inline void* operator new(size_t, seg *_ls, seg *_rs, int _mx, int _sum) {
static seg *mempool, *C;
if(mempool == C) mempool = (C = new seg[1<<15]) + (1<<15);
C->ls = _ls;
C->rs = _rs;
C->mx = _mx;
C->sum = _sum;
return C++;
}
}*rt[MAXN];
inline void update(seg *x) {
x->mx = x->sum = 0;
if(x->ls) x->mx = max(x->mx, x->ls->mx), x->sum += x->ls->sum;
if(x->rs) x->mx = max(x->mx, x->rs->mx), x->sum += x->rs->sum;
}
void insert(seg *&x, int l, int r, int pos, int val) {
if(!x) x = new(0x0, 0x0, 0, 0) seg;
if(l == r) {
x->sum = x->mx = val;
return;
}
int mid = (l + r) >> 1;
if(pos <= mid) insert(x->ls, l, mid, pos, val);
else insert(x->rs, mid+1, r, pos, val);
update(x);
}
int querysum(seg *p, int l, int r, int x, int y) {
if(!p) return 0;
if(l == x && r == y) return p->sum;
int mid = (l + r) >> 1;
if(y <= mid) return querysum(p->ls, l, mid, x, y);
else if(x > mid) return querysum(p->rs, mid+1, r, x, y);
else return querysum(p->ls, l, mid, x, mid) + querysum(p->rs, mid+1, r, mid+1, y);
}
int querymx(seg *p, int l, int r, int x, int y) {
if(!p) return 0;
if(l == x && r == y) return p->mx;
int mid = (l + r) >> 1;
if(y <= mid) return querymx(p->ls, l, mid, x, y);
else if(x > mid) return querymx(p->rs, mid+1, r, x, y);
else return max(querymx(p->ls, l, mid, x, mid), querymx(p->rs, mid+1, r, mid+1, y));
}
}
inline int Sum(SegmentTree::seg *r, int x, int y) {
int res = 0;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
res += SegmentTree::querysum(r, 1, n, dfn[top[x]], dfn[x]);
x = fa[top[x]];
}
if(dep[x] < dep[y]) swap(x, y);
res += SegmentTree::querysum(r, 1, n, dfn[y], dfn[x]);
return res;
}
inline int Max(SegmentTree::seg *r, int x, int y) {
int res = 0;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
res = max(res, SegmentTree::querymx(r, 1, n, dfn[top[x]], dfn[x]));
x = fa[top[x]];
}
if(dep[x] < dep[y]) swap(x, y);
res = max(res, SegmentTree::querymx(r, 1, n, dfn[y], dfn[x]));
return res;
}
int c[MAXN], w[MAXN];
int main() {
memset(fir, -1, sizeof fir);
read(n), read(m);
for(int i = 1; i <= n; ++i) read(w[i]), read(c[i]);
for(int x, y, i = 1; i < n; ++i) {
read(x), read(y);
Add(x, y), Add(y, x);
}
dfs(1); dfs2(1, 1);
for(int i = 1; i <= n; ++i) SegmentTree::insert(SegmentTree::rt[c[i]], 1, n, dfn[i], w[i]);
int x, y; char s[2];
while(m--) {
while(!isalpha(s[0] = getchar())); s[1] = getchar();
read(x), read(y);
if(s[0] == 'C' && s[1] == 'W') SegmentTree::insert(SegmentTree::rt[c[x]], 1, n, dfn[x], w[x]=y);
else if(s[0] == 'C' && s[1] == 'C') SegmentTree::insert(SegmentTree::rt[c[x]], 1, n, dfn[x], 0), c[x] = y, SegmentTree::insert(SegmentTree::rt[c[x]], 1, n, dfn[x], w[x]);
else if(s[0] == 'Q' && s[1] == 'S') printf("%d\n", Sum(SegmentTree::rt[c[x]], x, y));
else printf("%d\n", Max(SegmentTree::rt[c[x]], x, y));
}
}
BZOJ 3531: [Sdoi2014]旅行 (树剖+动态开点线段树)的更多相关文章
- BZOJ3531 树剖 + 动态开点线段树
https://www.lydsy.com/JudgeOnline/problem.php?id=3531 首先这题意要求树链上的最大值以及求和,其树链剖分的做法已经昭然若揭 问题在于这次的信息有宗教 ...
- CF915E Physical Education Lessons 动态开点线段树
题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...
- BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树
题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- bzoj3531: [Sdoi2014]旅行 (树链剖分 && 动态开点线段树)
感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- bzoj 3531: [Sdoi2014]旅行
Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. ...
- NFLSOJ #917 -「lych_cys模拟题2018」橘子树(树剖+ODT+莫反统计贡献的思想+动态开点线段树)
题面传送门 sb 出题人不在题面里写 \(b_i=0\) 导致我挂成零蛋/fn/fn 首先考虑树链剖分将路径问题转化为序列上的问题,因此下文中简称"位置 \(i\)"表示 DFS ...
- [ZJOI2019]语言(树链剖分+动态开点线段树+启发式合并)
首先,对于从每个点出发的路径,答案一定是过这个点的路径所覆盖的点数.然后可以做树上差分,对每个点记录路径产生总贡献,然后做一个树剖维护,对每个点维护一个动态开点线段树.最后再从根节点开始做一遍dfs, ...
随机推荐
- 2019牛客暑期多校训练营(第七场)-E Find the median (线段树+离散化 区间为点)
题目链接:https://ac.nowcoder.com/acm/contest/887/E 题意:给出L[i],R[i],每次添加L[i]...R[i],求出此时的中位数. 思路:因为添加的数范围为 ...
- 使用SecureCRT连接虚拟机中Linux系统 和 虚拟机网络配置
使用SecureCRT连接步骤:1.首先打开虚拟机,点击左上角的编辑,再点击虚拟网络编辑器(已经进行虚拟网络编辑的忽略此步骤,直接进行第二步) 点击VMnet8网络,点击更改设置,此步骤需要管理员权限 ...
- Oracle解决空表不导出
Select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 or num_rows ...
- 用python实现自己的http服务器——多进程、多线程、协程、单进程非堵塞版、epoll版
了解http协议 http请求头 GET / HTTP/1.1 Host: www.baidu.com Connection: keep-alive Pragma: no-cache Cache-Co ...
- go intall的使用
1.首先GOPATH路径指向src的上级目录 2.设置GOBIN路径指向bin目录 3.查看环境配置 4.go install 在src目录下 5.完成 6.pkg ide编译运行一下自动生成
- mybatis中collection子查询注入参数为null
具体实现参照网上,但是可能遇到注入参数为null的情况,经过查阅及自己测试记录一下: 子查询的参数中,有<if test="">之类,需要指定别名,通过 http:// ...
- 关于VSS(Volume Shadow Copy Service)一
在开发windows VSS应用程序时 我们应该先下载相关SDK,微软描述如下 When developing your own VSS application, you should observe ...
- MFC 下调试 出现 warning : fail to load indicator string 0x0069
MFC 下调试 出现 warning : fail to load indicator string 0x0069 就是程序状态栏每一个标识列中至少有一个值没有初始值 或初始值为空 导致程序没有获取到 ...
- js之数据类型(对象类型——构造器对象——函数1)
函数它只定义一次,但可能被多次的执行和调用.JavaScript函数是参数化的,函数的定义会包括形参和实参.形参相当于函数中定义的变量,实参是在运行函数调用时传入的参数. 一.函数定义 函数使用fun ...
- 4.Linux用户与权限管理
Linux 系统是一个多用于多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统 新增用户: useradd 新用户名 设置密码:pa ...