SCOI2018 树
树
时间限制 3000ms
内存限制 64MB
【题目描述】
在大小为 N 的树上,点从 1 到 N 标号,第 i 个点有权值 Ai,现在需要支持两种操作:
第一种操作格式为“1 U”,表示询问从 U 出发的简单路径,经过的点权值之和的最大值;
第二种操作格式为“2 U V”,表示将 U 的权值修改为 V。
【输入格式】
第一行两个整数 N 和 M,表示树的大小和操作数;
第二行 N-1 个整数,第 i 个整数 Pi(1<=Pi<=i)表示第 i+1 个点与 Pi 有边相连;
第三行 N 个整数,第 i 个整数 Ai 表示第 i 个点的点权;
接下来 M 行,每行为一个询问操作“1 U”或修改操作“2 U V”,按操作发生的先后顺序给出。
【输出格式】
对于每个询问操作,输出一个整数,即经过的点权值之和的最大值。
【样例输入 1】
6 7
1 1 1 3 3
-1 2 -3 4 -5 6
1 2
1 5
1 6
2 4 5
1 2
1 5
1 6
【样例输出 1】
5
-2
6
6
-2
7
【数据范围】
对于 10%的数据,满足:
1<=N<=1000,1<=M<=1000
对于另外 20%的数据,不存在修改操作
对于另外 20%的数据,满足 Pi=i
对于 100%的数据,满足:
1<=N<=100000,1<=M<=100000
1<=Pi<=i,-10000<=Ai<=10000
1<=U<=n,-10000<=V<=10000
分析
如果没有修改,那么就是一个简单的换根DP,选儿子中的最大值或者0即可。有修改的话,就要用到动态DP,如果用LCT维护的话换根就很方便了,维护正反矩阵乘积即可。矩阵转移为:
v[i] & v[i]+g[i].max & v[i] \\
-\infty & 0 & -\infty \\
-\infty & -\infty & 0
\end{bmatrix}*
\begin{bmatrix}
f(i+1)\\
0\\
0
\end{bmatrix}
\]
比较麻烦的是轻儿子的向上更新,由于要选最大值,所以要对每个节点维护一个平衡树(multiset),支持快速插入删除以及查询最大值。这个操作的复杂度应该跟splay一起均摊。
时间复杂度\(O(n \log n + 27 m \log n)\)。
代码
不开O2=TLE,开了O2跑得过动态点分治。很有必要学习动态点分治了。
co int N=1e5+1;
co ll INF=1e18;
struct matrix{
ll a[3][3];
il ll*operator[](int i) {return a[i];}
il co ll*operator[](int i)co {return a[i];}
il void init(ll v,co multiset<ll>&g){
a[0][0]=v,a[0][1]=v+(g.size()?*g.rbegin():0),a[0][2]=v;
a[1][0]=-INF,a[1][1]=0,a[1][2]=-INF;
a[2][0]=-INF,a[2][1]=-INF,a[2][2]=0;
}
il ll get() {return max(a[0][0],max(a[0][1],a[0][2]));}
il matrix operator*(co matrix&b)co{
matrix c;for(rg int i=0;i<3;++i) fill(c[i],c[i]+3,-INF);
for(rg int i=0;i<3;++i)
for(rg int j=0;j<3;++j)
for(rg int k=0;k<3;++k) c[i][j]=max(c[i][j],a[i][k]+b[k][j]);
return c;
}
}p1[N],p2[N];
int fa[N],ch[N][2];
ll v[N];
multiset<ll> g[N];
#define lc ch[x][0]
#define rc ch[x][1]
il bool nroot(int x) {return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
il void pushup(int x){
p1[x].init(v[x],g[x]),p2[x].init(v[x],g[x]);
if(lc) p1[x]=p1[lc]*p1[x],p2[x]=p2[x]*p2[lc];
if(rc) p1[x]=p1[x]*p1[rc],p2[x]=p2[rc]*p2[x];
}
il void rotate(int x){
int y=fa[x],z=fa[y],l=ch[y][1]==x,r=l^1;
if(nroot(y)) ch[z][y==ch[z][1]]=x;fa[x]=z;
ch[y][l]=ch[x][r],fa[ch[x][r]]=y;
ch[x][r]=y,fa[y]=x;
pushup(y);
}
il void splay(int x){
for(int y,z;nroot(x);rotate(x)){
y=fa[x],z=fa[y];
if(nroot(y)) rotate(y==ch[z][1]^x==ch[y][1]?x:y);
}
pushup(x);
}
il void access(int x){
for(int y=0;x;x=fa[y=x]){
splay(x);
if(rc) g[x].insert(p1[rc].get());
if(y) g[x].erase(g[x].find(p1[y].get()));
rc=y,pushup(x);
}
}
int main(){
freopen("tree.in","r",stdin),freopen("tree.out","w",stdout);
int n=read<int>(),m=read<int>();
for(rg int i=2;i<=n;++i) read(fa[i]);
for(rg int i=1;i<=n;++i) read(v[i]);
for(rg int i=n;i>=1;--i) p1[i].init(v[i],g[i]),p2[i].init(v[i],g[i]),g[fa[i]].insert(p1[i].get());
for(int u,v;m--;){
if(read<int>()==1){
read(u);
access(u),splay(u);
printf("%lld\n",p2[u].get());
}
else{
read(u),read(v);
access(u),splay(u),::v[u]=v,pushup(u);
}
}
return 0;
}
SCOI2018 树的更多相关文章
- 2018.10.18 NOIP训练 [SCOI2018]Pipi 酱的日常(线段树)
传送门 线段树好题啊. 题目要求的是sum−a−b−c+maxsum-a-b-c+maxsum−a−b−c+max{∣a+v∣+∣b+v∣+∣c+v∣|a+v|+|b+v|+|c+v|∣a+v∣+∣b ...
- B树——算法导论(25)
B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...
- ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单
前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- HDU1671——前缀树的一点感触
题目http://acm.hdu.edu.cn/showproblem.php?pid=1671 题目本身不难,一棵前缀树OK,但是前两次提交都没有成功. 第一次Memory Limit Exceed ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- bzoj3207--Hash+主席树
题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...
- bzoj1901--树状数组套主席树
树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...
随机推荐
- 使用wkwebview时,push后,再pop返回,报错
使用wkwebview时,push后,再pop返回,报错 Cannot form weak reference to instance (xxxx) of class xxxx. It is poss ...
- spring结合shiro的学习总结
pom文件加入 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-c ...
- ROS初探--意义、基本模块
顾虑就使我们都变成了懦夫,使得那果断的本色蒙上了一层思虑的惨白的容颜,本来可以做出伟大的事业,由于思虑就化为乌有了,丧失了行动的能力.-----哈姆雷特 ROS: Robot Operating Sy ...
- CSS3 实现别样图型
1.爱心 利用 div 的正方形和伪类的圆型组合而成 <!DOCTYPE html> <html> <head> <meta charset="UT ...
- triples I(按位或运算及3的特性)(2019牛客暑期多校训练营(第四场)D)
示例1: 输入: 2 3 7 输出: 1 32 3 6 说明:3=3, (3|6)=7 题意:输出尽可能少的数字,他们的按位或结果为输入的数字a. 题解:(表示看不懂题解,看山东大佬的代码看懂的)首先 ...
- Scala 数组操作之数组转换
使用yield和函数式编程转换数组 // 对Array进行转换,获取的还是Array val a = Array(1, 2, 3, 4, 5) val a2 = for (ele <- a) y ...
- VMware Workstation Pro 15 序列号
VMware Workstation Pro 15 序列号: GA70H-8TYE2-H886P-04YZC-YVA84 YG5H2-ANZ0H-M8ERY-TXZZZ-YKRV8 UG5J2-0ME ...
- java EE学习之数据库操作
jdbc开发流程 注册驱动 建立连接(Connection) 创建运行SQL的语句(Statement) 运行语句 处理运行结果(ResultSet) 释放资源 注冊驱动有三种方式: Class.fo ...
- collections.defaultdict()的使用
这里的defaultdict(function_factory)构建的是一个类似dictionary的对象,其中keys的值,自行确定赋值,但是values的类型,是function_factory的 ...
- MLP神经网络实例--手写识别
1.导入MNIST数据集 直接使用fetch_mldata会报错,错误信息是python3.7把fetch_mldata方法移除了,所以需要单独下载数据集从这个网站上下载数据集: https://gi ...