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 ...
随机推荐
- 笔记-python-float(‘inf’)
笔记-python-float(‘inf’) 看算法时发现了flaot(‘inf’). Python中可以用如下方式表示正负无穷: float("inf"), float(&quo ...
- 成都Uber优步司机奖励政策(1月28日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- Java >>>运算符 和 >> 运算符
>>> 在java 表示有符号右移.什么意思呢?就是最高位符号位也会移动. 我们知道,>>表示有符号右移. -1>> 1 = -1 -1>>2 = ...
- android 8.0 Account行为变更 账号系统
我们有个方法,是判断系统的账号有没有登录. public static boolean isAccountLogin(Context context) { String df = "com. ...
- Spark性能优化--开发调优与资源调优
参考: https://tech.meituan.com/spark-tuning-basic.html https://zhuanlan.zhihu.com/p/22024169 一.开发调优 1. ...
- unity share current game screen
using UnityEngine; using System.Collections; using UnityEngine.UI; using System.IO; public class Tak ...
- JS实现对数组的去重
JS实现对数组的去重 $scope.validateContect = function(text) { var arr = text; // 若传入的数据为string类型,用逗号分隔 if((ty ...
- TW实习日记:第24-25天
项目的交付期是真的赶...一直在不断地修改一些小bug,然后消息推送功能出了一个问题,就是不知道为什么PC端会发送两次消息到移动端后台.其中第一条正常第二条会有乱码不正常,可以说是很奇怪了,一开始都认 ...
- linux学习总结----mongoDB总结
dbhelper.py 用户登录和注册(加密算法) 加密导包 import hashlib 或者使用Md5 加密 MongoDB ->JSON service mysql start servi ...
- JAVA基础学习之路(六)数组与方法参数的传递
通常,向方法中传递的都是基本数据类型,而向方法中传递数组时,就需要考虑内存的分配 public class test2 { public static void main(String args[]) ...