BZOJ 1036 树的统计(树链剖分)
点权树链剖分模板题。
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Edge{int p, next;}edge[N<<];
int head[N], cnt, node[N], n;
int seg[N<<][], fa[N], size[N], dep[N], p[N], top[N], son[N], pos; void add_edge(int u, int v){edge[cnt].p=v; edge[cnt].next=head[u]; head[u]=cnt++;}
void init(){cnt=; mem(son,-); pos=;}
void dfs(int x, int pre, int d)
{
fa[x]=pre; dep[x]=d; size[x]=;
for (int i=head[x]; i; i=edge[i].next) {
int v=edge[i].p;
if (v==pre) continue;
dfs(v,x,d+);
size[x]+=size[v];
if (son[x]==-||size[v]>size[son[x]]) son[x]=v;
}
}
void get_pos(int x, int sp)
{
top[x]=sp; p[x]=pos++;
if (son[x]==-) return ;
get_pos(son[x],sp);
for (int i=head[x]; i; i=edge[i].next) {
int v=edge[i].p;
if (v!=son[x]&&v!=fa[x]) get_pos(v,v);
}
}
void push_up(int p)
{
seg[p][]=max(seg[p<<][], seg[p<<|][]);
seg[p][]=seg[p<<][]+seg[p<<|][];
}
void update(int p, int l, int r, int L, int val)
{
if (L>r||L<l) return ;
if (L==l&&L==r) seg[p][]=seg[p][]=val;
else {
int mid=(l+r)>>;
update(lch,L,val); update(rch,L,val);
push_up(p);
}
}
int query(int p, int l, int r, int L, int R, int flag)
{
if (L>r||R<l) {
if (flag) return ;
else return -INF;
}
if (L<=l&&R>=r) return seg[p][flag];
int mid=(l+r)>>;
if (flag) return query(lch,L,R,flag)+query(rch,L,R,flag);
else return max(query(lch,L,R,flag),query(rch,L,R,flag));
}
int Qtree(int l, int r, int flag)
{
int f1=top[l], f2=top[r], ans;
if (flag) ans=;
else ans=-INF;
bool mark=false;
while (f1!=f2) {
mark=true;
if (dep[f1]<dep[f2]) swap(f1,f2), swap(l,r);
if (flag==) ans=max(ans,query(,,n,p[f1],p[l],flag));
else ans+=query(,,n,p[f1],p[l],flag);
l=fa[f1]; f1=top[l];
}
if (dep[l]>dep[r]) swap(l,r);
if (flag==) ans=max(ans,query(,,n,p[l],p[r],flag));
else ans+=query(,,n,p[l],p[r],flag);
return ans;
}
int main ()
{
int u, v, q, l, r;
char flag[];
init();
scanf("%d",&n);
FO(i,,n) scanf("%d%d",&u,&v), add_edge(u,v), add_edge(v,u);
dfs(,,);
get_pos(,);
FOR(i,,n) scanf("%d",node+i), update(,,n,p[i],node[i]);
scanf("%d",&q);
while (q--) {
scanf("%s%d%d",flag,&l,&r);
if (flag[]=='C') update(,,n,p[l],r);
else printf("%d\n",Qtree(l,r,flag[]=='S'));
}
return ;
}
BZOJ 1036 树的统计(树链剖分)的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count-树链剖分(点权)(单点更新、路径节点最值、路径求和)模板,超级认真写了注释啊啊啊
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 23015 Solved: 9336[Submit ...
- 树的统计Count---树链剖分
NEFU专项训练十和十一——树链剖分 Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t ...
- BZOJ 1036 树的统计-树链剖分
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...
- BZOJ-1036 树的统计Count 链剖线段树(模板)=(树链剖分+线段树)
潇爷昨天刚刚讲完...感觉得还可以...对着模板打了个模板...还是不喜欢用指针.... 1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Lim ...
- BZOJ.3252.攻略(贪心 长链剖分/线段树)
题目链接 贪心,每次选价值最大的一条到根的链.比较显然(不选白不选). 考虑如何维护这个过程.一个点的价值选了就没有了,而它只会影响它子树里的点,可以用DFS序+线段树修改.而求最大值也可以用线段树. ...
- [ZJOI2008]树的统计——树链剖分
本题是一个树链剖分裸题,由于比较菜,老是RE,后来发现是因为使用了全局变量. /************************************************************ ...
- bzoj1036 树的统计 树链剖分模板
题意:给出树上任意两点,求路径上的值的和与最大值,带单点修改操作 树链剖分思路: 1.对树进行dfs求出点的深度和父亲节点,然后求出轻重儿子(重儿子就是点最多的那个子树,其余都是轻儿子),用一个son ...
- zjoi 2008 树的统计——树链剖分
比较基础的一道树链剖分的题 大概还是得说说思路 树链剖分是将树剖成很多条链,比较常见的剖法是按儿子的size来剖分,剖分完后对于这课树的询问用线段树维护——比如求路径和的话——随着他们各自的链向上走, ...
- BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...
- [luogu P2590 ZJOI2008] 树的统计 (树链剖分)
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
随机推荐
- IIC总线协议和时序
IIC标准速率为100Kbit/s,快速模式400Kbit/s,支持多机通信,支持多主控模块,但是同一时刻只允许有一个主控.由数据线SDA和时钟SCL构成串行总线:每个电路模块都有唯一地址.I2C设备 ...
- Java面向对象之抽象方法&接口
在开始写抽象类之前,有一个问题我觉得想清楚会对理解抽象类很有帮助:那就是为什么要设计抽象类? 难道用类还不够么,为什么要设计出抽象类这样一个东西.我们可以换个角度来理解,就是有些类本来就是不应该被实例 ...
- 【NIS】深入了解NIS
1 简介 NIS( NetworkInformation Service)提供了一个网络黄页的功能,当用户登录系统时,Linux系统会到NIS主机上去寻找用户使用的帐号密码信息加以比对,以提供用户登 ...
- Python-特殊变量
from test import test ''' __mame__ __file__ __cache__ __package__ ''' # import os # 获取这个当前文件的绝对路径 # ...
- Python常见的脚本汇总
1.冒泡排序 lis = [56,12,1,8,354,10,100,34,56,7,23,456,234,-58] def sortport(): for i in range(len(lis)-1 ...
- 树和二叉树 -数据结构(C语言实现)
读数据结构与算法分析 树的概念 一棵树是一些节点的集合,可以为空 由称做根(root)的节点以及0个或多个非空子树组成,子树都被一条来自根的有向边相连 树的实现 思路 孩子兄弟表示法:树中的每个节点中 ...
- 机器学习-线性回归LinearRegression
概述 今天要说一下机器学习中大多数书籍第一个讲的(有的可能是KNN)模型-线性回归.说起线性回归,首先要介绍一下机器学习中的两个常见的问题:回归任务和分类任务.那什么是回归任务和分类任务呢?简单的来说 ...
- Caused by: java.lang.NoClassDefFoundError: javax/el/ELManager
出现问题的原因: 在将springboot项目部署到Linux下的Tomcat中,项目无法正常启动(本地能正常运行),Tomcat启动日志中出现: Caused by: java.lang.NoCla ...
- POJ 3384 Feng Shui(计算几何の半平面交+最远点对)
Description Feng shui is the ancient Chinese practice of placement and arrangement of space to achie ...
- 为什么23种设计模式中没有MVC
GoF (Gang of Four,四人组, <Design Patterns: Elements of Reusable Object-Oriented Software>/<设计 ...