题目链接: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. 【Linux相识相知】文本处理工具之grep\egrep\fgrep及正则表达式

    常说Linux上有文本处理的三剑客,grep.sed和awk,本文就grep做出详细的描述,并引出正则表达式. grep NAME:打印模式匹配的行 SYNOPISIS: grep [OPTIONS] ...

  2. MAC 下安装RabbitMQ

    1.使用brew来安装 RabbitMQ(地址:http://www.rabbitmq.com/install-standalone-mac.html ) 2.安装目录 /usr/local/Cell ...

  3. solidity合约面向对象

    1. 属性[状态变量]的访问权限 public  internal[合约属性默认的权限]  private 说明:属性默认访问全向为internal,internal和private类型的属性,外部是 ...

  4. Nginx反向代理与负载均衡[转]

    nginx启动和关闭(centos平台) /usr/local/nginx/sbin/nginx #启动 /usr/local/nginx/sbin/nginx -s reload #平滑启动 vi ...

  5. HTML表格相关元素

    <table> 标签定义 HTML 表格.简单的 HTML 表格由 table 元素以及一个或多个 tr.th 或 td 元素组成.tr 元素定义表格行,th 元素定义表头,td 元素定义 ...

  6. sass函数:@function

    sass定义了很多函数可供使用,当然你也可以自己定义函数,以@fuction开始. sass的官方函数链接为:sass fuction,实际项目中我们使用最多的应该是颜色函数,而颜色函数中又以ligh ...

  7. 概述File i/o

    1.File对象既可表示文件,也可表示目录(文件夹). 2. 创建一个File对象 File file = new File (String pathName[文件路径名]); 3.在Windows操 ...

  8. JQuery和html+css实现鼠标点击放烟花

    <!DOCTYPE html> <html> <head><meta http-equiv="Content-Type" content= ...

  9. 有关table布局时tr 属性display:block显示布局错乱

    display:block display:block是可以把非块级元素强制转换为块级元素显示,如内嵌元素span,原来不支持设置宽高,宽度是由内容撑开的; display:table-row tab ...

  10. Kafka监控利器

    开发过程中,kafka几乎是标配的Mq,如果有一个kafka的监控助手,哪就更完美了,常用的kafka监控工具有 KafkaOffsetMonitor .Kafka Manager.Capillary ...