luogu P4719 【模板】动态 DP 矩阵乘法 + LCT
Code:
- // luogu-judger-enable-o2
- //Dynamic DP with LCT
- #include<bits/stdc++.h>
- #define ll long long
- #define setIO(s) freopen(s".in","r",stdin)
- #define maxn 100002
- #define inf 100000000
- using namespace std;
- //Link cut tree
- void de()
- {
- printf("ok\n");
- }
- namespace LCT
- {
- struct Matrix
- {
- ll a[2][2];
- ll*operator[](int x){ return a[x];}
- }t[maxn],tmp[maxn];
- Matrix operator*(Matrix a,Matrix b)
- {
- Matrix c;
- c[0][0]=max(a[0][0]+b[0][0],a[0][1]+b[1][0]);
- c[0][1]=max(a[0][0]+b[0][1],a[0][1]+b[1][1]);
- c[1][0]=max(a[1][0]+b[0][0],a[1][1]+b[1][0]);
- c[1][1]=max(a[1][0]+b[0][1],a[1][1]+b[1][1]);
- return c;
- }
- //tmp :: 虚儿子信息
- //t :: 树剖实际转移矩阵
- #define lson ch[x][0]
- #define rson ch[x][1]
- int ch[maxn][2],f[maxn];
- int isRoot(int x)
- {
- return !(ch[f[x]][0]==x || ch[f[x]][1]==x);
- }
- int get(int x)
- {
- return ch[f[x]][1]==x;
- }
- void pushup(int x)
- {
- t[x]=tmp[x];
- if(lson) t[x]=t[lson]*t[x];
- if(rson) t[x]=t[x]*t[rson];
- }
- void rotate(int x)
- {
- int old=f[x],fold=f[old],which=get(x);
- if(!isRoot(old)) ch[fold][ch[fold][1]==old]=x;
- ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
- ch[x][which^1]=old,f[old]=x,f[x]=fold;
- pushup(old),pushup(x);
- }
- void splay(int x)
- {
- int u=x;
- while(!isRoot(u)) u=f[u];
- u=f[u];
- for(int fa;(fa=f[x])!=u;rotate(x))
- if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x);
- }
- void Access(int x)
- {
- for(int y=0;x;y=x,x=f[x])
- {
- splay(x);
- if(rson)
- {
- tmp[x][0][0]+=max(t[rson][0][0],t[rson][1][0]);
- tmp[x][1][0]+=t[rson][0][0];
- }
- if(y)
- {
- tmp[x][0][0]-=max(t[y][0][0],t[y][1][0]);
- tmp[x][1][0]-=t[y][0][0];
- }
- tmp[x][0][1]=tmp[x][0][0];
- rson=y,pushup(x);
- }
- }
- };
- //variables
- int DP[maxn][2];
- int V[maxn],hd[maxn],to[maxn<<1],nex[maxn<<1];
- int n,Q,edges;
- void add(int u,int v){ nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; }
- //build graph
- void dfs(int u,int ff)
- {
- LCT::f[u]=ff;
- DP[u][0]=0;
- DP[u][1]=V[u];
- for(int i=hd[u];i;i=nex[i])
- {
- int v=to[i];
- if(v==ff) continue;
- dfs(v,u);
- DP[u][0]+=max(DP[v][1],DP[v][0]);
- DP[u][1]+=DP[v][0];
- }
- LCT::tmp[u]=(LCT::Matrix){ DP[u][0], DP[u][0], DP[u][1], -inf};
- LCT::t[u]=LCT::tmp[u];
- }
- //主程序~
- int main()
- {
- // setIO("input");
- scanf("%d%d",&n,&Q);
- for(int i=1;i<=n;++i) scanf("%d",&V[i]);
- for(int i=1,u,v;i<n;++i)
- {
- scanf("%d%d",&u,&v);
- add(u,v),add(v,u);
- }
- dfs(1,0);
- while(Q--)
- {
- int x,y;
- scanf("%d%d",&x,&y);
- LCT::Access(x);
- LCT::splay(x);
- LCT::tmp[x][1][0]+=(ll)y-V[x];
- V[x]=y;
- LCT::pushup(x);
- LCT::splay(1);
- printf("%lld\n",max(LCT::t[1][0][0], LCT::t[1][1][0]));
- }
- return 0;
- }
luogu P4719 【模板】动态 DP 矩阵乘法 + LCT的更多相关文章
- Luogu P4643 【模板】动态dp(矩阵乘法,线段树,树链剖分)
题面 给定一棵 \(n\) 个点的树,点带点权. 有 \(m\) 次操作,每次操作给定 \(x,y\) ,表示修改点 \(x\) 的权值为 \(y\) . 你需要在每次操作之后求出这棵树的最大权独立集 ...
- [luogu 4719][模板]动态dp
传送门 Solution \(f_{i,0}\) 表示以i节点为根的子树内,不选i号节点的最大独立集 \(f_{i,1}\)表示以i节点为根的子树内,选i号节点的最大独立集 \(g_{i,0}\) 表 ...
- 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法
题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...
- 【bzoj3329】Xorequ 数位dp+矩阵乘法
题目描述 输入 第一行一个正整数,表示数据组数据 ,接下来T行每行一个正整数N 输出 2*T行第2*i-1行表示第i个数据中问题一的解, 第2*i行表示第i个数据中问题二的解, 样例输入 1 1 样例 ...
- [模板] 动态dp
用途 对于某些树形dp(目前只会树上最大权独立集或者类似的),动态地修改点权,并询问修改后的dp值 做法(树剖版) 以最大权独立集为例 设$f[x][0/1]$表示x选不选,这棵子树的最大权独立集大小 ...
- 【BZOJ-4386】Wycieczki DP + 矩阵乘法
4386: [POI2015]Wycieczki Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 197 Solved: 49[Submit][Sta ...
- [模板][题解][Luogu1939]矩阵乘法加速递推(详解)
题目传送门 题目大意:计算数列a的第n项,其中: \[a[1] = a[2] = a[3] = 1\] \[a[i] = a[i-3] + a[i - 1]\] \[(n ≤ 2 \times 10^ ...
- LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)
题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...
- ZOJ - 3216:Compositions (DP&矩阵乘法&快速幂)
We consider problems concerning the number of ways in which a number can be written as a sum. If the ...
随机推荐
- 记一次ruby的安装
1,下载rubyinstall 安装包及devkit包 登陆网站 :http://rubyinstaller.org/downloads/ 安装rubyinstall包时添加到环境变量 2,安装完in ...
- 【翻译自mos文章】在12c数据库中,哪种audit trail 受到支持?
在12c数据库中,哪种audit trail 受到支持? 来源于:What Audit Trail Types Are Supported For A 12c Database? (文档 ID 198 ...
- LeetCode之LCP(Longest Common Prefix)问题
这个也是简单题目.可是关键在于题意的理解. 题目原文就一句话:Write a function to find the longest common prefix string amongst an ...
- ActionBar第一课简单介绍
.ActionBar简单介绍 ActionBar是显示在界面顶部的标题栏. 官方推荐开发者尽量使用 ActionBar代替OptionsMenu和TabHost. 典型应用方式有: 使用导航栏中的应用 ...
- hook 鼠标键盘消息实例分析
1.木马控制及通信方法包含:双管道,port重用.反弹技术.Hook技术,今天重点引用介绍一下hook的使用方法,hook信息后能够将结果发送到hacker邮箱等.实现攻击的目的. 转自:http:/ ...
- hihocoder 1680 hiho字符串2 dp求方案数+递归
我们定义第一代hiho字符串是"hiho". 第N代hiho字符串是由第N-1代hiho字符串变化得到,规则是: h -> hio i -> hi o -> ho ...
- B1391 [Ceoi2008]order 最大权闭合图 最小割
啊啊啊,假的题吧!!!我用的当前弧优化T了6个点,其他人不用优化AC!!!震惊!!!当前弧优化是假的吧!!! 到现在我也没调出来...大家帮我看看为啥70.... 来讲一下这个题的思路,就是设一个源点 ...
- Java-java-com-util-common-service:TreeService.java
ylbtech-Java-java-com-util-common-service:TreeService.java 1.返回顶部 1. package com.shineyoo.manager.ut ...
- go之结构体
一.关于结构体 简述 1.go 语言的切片可以存储同一类型的数据,但是结构体可以为不同项定义不同的数据类型 2.结构体是有一系列具有相同类型或不同类型的数据构成的数据集合 3.因为go 没有类似于类的 ...
- 2-bitmap
在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数. 思路: bitmap用一个bit来代表存在还是不存在,现在我们要判断重不重复,则需要三个状态:不存在,存在一个,存在多个.2b ...