题目链接:https://www.luogu.org/problemnew/show/P2590

我想学树剖QAQ

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 31000;
int fa[maxn], dep[maxn], size[maxn], son[maxn], top[maxn], seg[maxn], rev[maxn<<2];
int sum[maxn<<2], num[maxn], mx[maxn];
struct edge{
int to, next;
}e[maxn<<2];
int head[maxn<<2], cnt;
int summ, maxx, n, m;
void query(int k, int l, int r, int L, int R)//区间查询
{
if(L > r||R < l) return;
if(L <= l&&r <= R)
{
summ += sum[k];
maxx = max(maxx, mx[k]);
return;
}
int mid = l+r>>1, res = 0;
if(mid >= L) query(k<<1, l, mid, L, R);
if(mid+1 <= R) query((k<<1)+1, mid+1, r, L, R);
}
void change(int k, int l, int r, int val, int pos)//单点修改
{
if(pos>r || pos<l) return;
if(l == r && r == pos)
{
sum[k] = val;
mx[k] = val;
return;
}
int mid = l+r>>1;
if(mid >= pos) change(k<<1, l, mid, val, pos);
if(mid+1 <= pos) change((k<<1)+1, mid+1, r, val, pos);
sum[k] = sum[k<<1]+sum[(k<<1)+1];
mx[k] = max(mx[k<<1], mx[(k<<1)+1]);
}
void dfs1(int u, int f)
{
int v;
size[u] = 1;
fa[u] = f;
dep[u] = dep[f]+1;
for(int i = head[u]; v = e[i].to, i; i = e[i].next)
{
if(v != f)
{
dfs1(v,u);
size[u] += size[v];
if(size[v] > size[son[u]])
son[u] = v;
}
}
}
void dfs2(int u, int f)
{
int v;
if(son[u])
{
seg[son[u]] = ++seg[0];
top[son[u]] = top[u];
rev[seg[0]] = son[u];
dfs2(son[u],u);
}
for(int i = head[u]; v = e[i].to, i; i = e[i].next)
{
if(!top[v])
{
seg[v] = ++seg[0];
rev[seg[0]] = v;
top[v] = v;
dfs2(v,u);
}
}
}
void build(int k, int l, int r)
{
int mid = l+r>>1;
if(l == r)
{
mx[k] = sum[k] = num[rev[l]];
return;
}
build(k<<1, l, mid);
build((k<<1)+1, mid+1, r);
sum[k] = sum[k<<1]+sum[(k<<1)+1];
mx[k] = max(mx[k<<1],mx[(k<<1)+1]);
}
inline int read()
{
char c;
int k = 1;
while((c = getchar())<'0' || c>'9')
if(c == '-') k = -1;
int res = c-'0';
while((c = getchar())>='0' && c<='9')
res = res*10+c-'0';
return res*k;
}
inline void add(int u, int v)
{
e[++cnt].next = head[u];
e[cnt].to = v;
head[u] = cnt;
}
inline void insert(int u, int v)
{
add(u, v);
add(v, u);
}
inline void ask(int u, int v)
{
int fu = top[u], fv = top[v];
while(fu != fv)
{
if(dep[fu]<dep[fv]) swap(u,v), swap(fu,fv);
query(1,1,seg[0],seg[fu],seg[u]);
u = fa[fu], fu = top[u];
}
if(dep[u]>dep[v]) swap(u,v);
query(1,1,seg[0],seg[u],seg[v]);
}
int main()
{
n = read();
for(int i = 1; i < n; i++)
insert(read(),read());
for(int i = 1; i <= n; i++)
num[i] = read();
dfs1(1,0);
seg[0] = seg[1] = rev[1] = top[1] = 1;
dfs2(1,0);
build(1,1,seg[0]);
m = read();
char opt[10];
int u, v;
for(int i = 1; i <= m; i++)
{
scanf("%s",opt+1);
u = read(); v = read();
if(opt[1] == 'C')
change(1,1,seg[0],v,seg[u]);
else
{
summ = 0;
maxx = -0x7fffffff;
ask(u,v);
if(opt[2] == 'M')
printf("%d\n",maxx);
else
printf("%d\n",summ);
}
}
return 0;
}

【luogu P2590 [ZJOI2008]树的统计】 题解的更多相关文章

  1. Luogu P2590 [ZJOI2008]树的统计

    最近在学树剖,看到了这题就做了 [ZJOI2008]树的统计 思路 从题面可以知道,这题是树剖题(要求的和模板没什么区别呀喂 就是在普通的树剖上加了一个最大值 所以可以知道就是树剖+特殊的线段树 线段 ...

  2. 洛谷P2590 [ZJOI2008]树的统计 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2590 树链剖分模板题. 剖分过程要用到如下7个值: fa[u]:u的父节点编号: dep[u]:u的深度: size[u]: ...

  3. BZOJ 1036 && Luogu P2590 [ZJOI2008]树的统计 树链剖分

    链剖裸题...你值得一做~ 用线段树多维护一个mx,少写一个tag #include<cstdio> #include<iostream> #define ll long lo ...

  4. [luogu P2590 ZJOI2008] 树的统计 (树链剖分)

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...

  5. Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)

    Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...

  6. P2590 [ZJOI2008]树的统计(树链剖分)

    P2590 [ZJOI2008]树的统计 虽然是入门树剖模板 但是我终于1A了(大哭) 懒得写啥了(逃 #include<iostream> #include<cstdio> ...

  7. [Luogu 2590] ZJOI2008 树的统计

    [Luogu 2590] ZJOI2008 树的统计 裸树剖不解释. 比板子还简单. #include <algorithm> #include <cstdio> #inclu ...

  8. P2590 [ZJOI2008]树的统计(LCT)

    P2590 [ZJOI2008]树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把 ...

  9. 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)

    P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...

随机推荐

  1. js获取当前日期,格式为YYYY-MM-DD

    //获取当前时间,格式YYYY-MM-DD function getNowFormatDate() { var date = new Date(); var seperator1 = "-& ...

  2. html和css(一)

    简单点来说html和css就是一起连在使用,有了html和css会使网页更加有活力,看起来更加的好看. html是做关于网页标签这一块相当于骨架,更深的还需要另一个来完成,那就是css,相当于向里面加 ...

  3. 浅谈------location

    今天在上班的时候碰到了要根据不同的页面随机添加栏目的问题,很简单的问题,想到了判断页面url是否含有某字符串来进行随机添加栏目...这就需要了解location对象. location 属性名 属性说 ...

  4. struts2返回结果类型

    在action下还有result标签 1.result不只有name,其实还有type result返回类型在struts-default.xml默认的配置文件中有定义,可以看到有result-typ ...

  5. MarkDown和流程图诠释你的代码

    写在前面:首先感谢导师-猴哥对我的认可(求多分享点编程经验.工具.多开课),学习编程是一个痛苦和快乐的过程,希望大家共勉 本文介绍MarkDown的基本语法.使用MarkDown画简单的流程图.使用X ...

  6. Mantis查看问题列表的列名修改_"P","#"两列

    在使用mantis的时候,点击菜单上的“查看问题”进去,就会罗列出当前的bug列表,可是列表的标题上存在着“P”和“#”的显示,个人觉得这两列在这里完全没有意义,或者说现有的显示使人觉得疑惑,究竟代表 ...

  7. mongodb 3.4 学习 (六)监控

    mongostat mongotop db.currentOp db.serverStatus() db.stats() db.collection.stats() # 复制集监控 rs.status ...

  8. mybatis中sql语句查询操作

    动态sql where if where可以自动处理第一个and. <!-- 根据id查询用户信息 --> <!-- public User findUserById(int id) ...

  9. 【NLP_Stanford课堂】句子切分

    依照什么切分句子——标点符号 无歧义的:!?等 存在歧义的:. 英文中的.不止表示句号,也可能出现在句子中间,比如缩写Dr. 或者数字里的小数点4.3 解决方法:建立一个二元分类器: 检查“.” 判断 ...

  10. Mysql Order By 注入总结

    前言 最近在做一些漏洞盒子后台项目的总结,在盒子多期众测项目中,发现注入类的漏洞占比较大.其中Order By注入型的漏洞也占挺大一部分比例,这类漏洞也是白帽子乐意提交的类型(奖金高.被过滤概率小). ...