洛谷.2590.[ZJOI2008]树的统计(树分块)
Update:这种分块写法...可以被卡掉啊...
好像没有靠谱的树分块写法...
/*
对树上节点进行分块,每个点记录dep,fa,val,Max,Sum,Max,Sum表示当前点在该块内的子树中权值最大值与和
节点i各值表示从root[i]到i一段路径的的对应值。因为求值时应是向上找到LCA,所以记录一个从根到叶的信息
修改一个点i时影响的只是该块内从fa[i]以下的点,暴力向下更新
查询路径时不断向上找LCA。注意每次都是让深度大的跳,以避免分类讨论
当两个点在一个块内时暴力一步步向上 直到LCA
存两组边,一是原图中的边,二是每个块内的关系边
*/
#include<cmath>
#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() getchar()
const int N=3e4+5,INF=0x3f3f3f3f;
int n,limit,val[N],rt[N],dep[N],fa[N],Max[N],Sum[N],Enum,H[N],nxt[N<<1],to[N<<1];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
void AddEdge(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void Build(int x,int &res)
{
if(res) rt[x]=rt[fa[x]],--res;
else rt[x]=x,res=limit;
for(int i=H[x];i;i=nxt[i])
if(to[i]!=fa[x])
dep[to[i]]=dep[x]+1,fa[to[i]]=x,Build(to[i],res);
}
void Update(int x,int Mx,int Sm)
{
Sm+=val[x], Sum[x]=Sm;
Mx=std::max(Mx,val[x]), Max[x]=Mx;
for(int i=H[x];i;i=nxt[i])
if(rt[x]==rt[to[i]] && to[i]!=fa[x])
Update(to[i],Mx,Sm);
}
int Query(int x,int y,bool f)
{
int sm=0,mx=-INF;
while(rt[x]!=rt[y])//不在同一块时直接用整块的信息
{
if(dep[x]<dep[y]) std::swap(x,y);
if(dep[rt[x]]<dep[rt[y]]) std::swap(x,y);
mx=std::max(mx,Max[x]), sm+=Sum[x];
x=fa[rt[x]];
}
while(x!=y)//在同一个块内,不能直接用整块的信息,一步步跳
{
if(dep[x]<dep[y]) std::swap(x,y);
mx=std::max(mx,val[x]), sm+=val[x];
x=fa[x];
}
// while(x!=y)
// {
// if(dep[x]<dep[y]) std::swap(x,y);
// if(rt[x]==rt[y])//在同一个块内,不能直接用整块的信息,一步步跳
// {
// mx=std::max(mx,val[x]), sm+=val[x];
// x=fa[x];
// }
// else
// {
// if(dep[rt[x]]<dep[rt[y]]) std::swap(x,y);
// mx=std::max(mx,Max[x]), sm+=Sum[x];
// x=fa[rt[x]];
// }
// }
mx=std::max(mx,val[x]), sm+=val[x];//Don't forget!!
return f?mx:sm;
}
int main()
{
n=read(),limit=pow(n,0.45);
// limit=sqrt(n);
for(int u,v,i=1;i<n;++i) u=read(),v=read(),AddEdge(u,v);
for(int i=1;i<=n;++i) Max[i]=val[i]=read();
int res=0;
Build(1,res);
for(int i=1;i<=n;++i)
if(rt[i]==i) Update(i,val[i],0);
int q=read(),u,v;char s[7];
while(q--)
{
scanf("%s",s),u=read(),v=read();
if(s[0]=='C')
{
val[u]=v;
if(u==rt[u]) Update(u,val[u],0);//显然不能从上一块更新
else Update(u,Max[fa[u]],Sum[fa[u]]);//是从当前节点更新,not fa[u]!fa[u]的Sum这样就多了
}
else if(s[1]=='M') printf("%d\n",Query(u,v,1));
else printf("%d\n",Query(u,v,0));
}
return 0;
}
洛谷.2590.[ZJOI2008]树的统计(树分块)的更多相关文章
- 洛谷P2607 [ZJOI2008]骑士(基环树)
传送门 首先这是一个有$n$个点$n$条边的图(据大佬们说这玩意儿叫做基环树?) 不难(完全没有)发现每个连通块里最多只有一个环 那么找到这个环,然后把它断开,再对它的两个端点分别跑树形dp 设$dp ...
- 洛谷 P3373 【模板】线段树 2
洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...
- 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)
P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...
- 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]
题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...
- 洛谷P5069 [Ynoi2015]纵使日薄西山(树状数组,set)
洛谷题目传送门 一血祭 向dllxl致敬! 算是YNOI中比较清新的吧,毕竟代码只有1.25k. 首先我们对着题意模拟,寻找一些思路. 每次选了一个最大的数后,它和它周围两个数都要减一.这样无论如何, ...
- 洛谷P3372 【模板】线段树 1
P3372 [模板]线段树 1 153通过 525提交 题目提供者HansBug 标签 难度普及+/提高 提交 讨论 题解 最新讨论 [模板]线段树1(AAAAAAAAA- [模板]线段树1 洛谷 ...
- 洛谷P2617 Dynamic Ranking(主席树,树套树,树状数组)
洛谷题目传送门 YCB巨佬对此题有详细的讲解.%YCB%请点这里 思路分析 不能套用静态主席树的方法了.因为的\(N\)个线段树相互纠缠,一旦改了一个点,整个主席树统统都要改一遍...... 话说我真 ...
- 洛谷P4891 序列(势能线段树)
洛谷题目传送门 闲话 考场上一眼看出这是个毒瘤线段树准备杠题,发现实在太难调了,被各路神犇虐哭qwq 考后看到各种优雅的暴力AC......宝宝心里苦qwq 思路分析 题面里面是一堆乱七八糟的限制和性 ...
- BZOJ3262/洛谷P3810 陌上花开 分治 三维偏序 树状数组
原文链接http://www.cnblogs.com/zhouzhendong/p/8672131.html 题目传送门 - BZOJ3262 题目传送门 - 洛谷P3810 题意 有$n$个元素,第 ...
随机推荐
- Python基础-封装与扩展、静态方法和类方法
一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数)名.参数不变,使用者的代码永远无需改变.这就提供一个 ...
- 【转】Shell编程基础篇-上
[转]Shell编程基础篇-上 1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应 ...
- 关于Java源文件中public类的问题
结论: 一个Java源文件中最多只能有一个public类,当有一个public类时,源文件名必须与之一致,否则无法编译: 如果源文件中没有一个public类,则文件名与类中没有一致性要求: 至于mai ...
- JavaScript的类型自动转换样例集合处
1.前言 如果Javascript期望使用一个字符串,它会把给定的值转换成字符串:如果Javascript期望使用一个数字,它会把给定的值转化成数字. 2.样例 2.1.字符串拼接时有数字 windo ...
- python+selenium四:iframe查看、定位、切换
iframe是HTML里面嵌套HTML的一种框架 1.查看iframe 1.Top Window:可直接定位 2.iframe#i:说明此元素在iframe上 3.iframe显示为空:(id或nam ...
- python 全栈开发,Day15(递归函数,二分查找法)
一.递归函数 江湖上流传这这样一句话叫做:人理解循环,神理解递归.所以你可别小看了递归函数,很多人被拦在大神的门槛外这么多年,就是因为没能领悟递归的真谛. 递归函数:在一个函数里执行再调用这个函数本身 ...
- 2018-2019-2 网络对抗技术 20165333 Exp4 恶意代码分析
2018-2019-2 网络对抗技术 20165333 Exp4 恶意代码分析 原理与实践说明 1.实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或E ...
- .NetCore下使用Prometheus实现系统监控和警报 (五)进阶自定义收集指标 之 Counter
Prometheus下面定了四种类型的收集方式,下面我们主要来来说下Counter的使用 Nuget导入Prometheus.AspNetCore包 下面先来看下我的Prometheus配置,这里我没 ...
- 接口隔离原则(Interface Segregation Principle, ISP)
使用多个专门的接口,而不使用单一的总接口 接口隔离有两种定义: Clients should not be forced to depend upon interfaces that they don ...
- LeetCode 4. Median of Two Sorted Arrays (分治)
两个有序的数组 nums1 和 nums2 维数分别为m,n.找所有数的中位数,复杂度 O(log (m+n)) 注意:奇偶个数,分治法求解,递归出口特殊处理.取Kth smallest数时,分治取m ...