题目大意:给你一颗$n$个点的树,点有点权,有$m$次操作,每次操作给定$x$,$y$,表示修改点$x$的权值为$y$。

你需要在每次操作之后求出这棵树的最大权独立集的权值大小。

数据范围:$n,m≤1e5$

我们显然可以得出一个$O(nm)$的暴力做法,每次修改完后$dp$一次,然而这个显然会超时。

考虑当树退化成链时的简单做法。

我们用线段树维护每个区间的答案。对于区间$[l,r]$,我们维护一个$2×2$的答案矩阵$ans$。

设$ans[0][0]$表示区间左端点可能被选择,右端点一定不被选择时的最大值。

设$ans[0][1]$表示区间左端点可能被选择,右端点可能被选择时的最大值。

设$ans[1][0]$表示区间左端点一定不被选择,右端点一定不被选择时的最大值。

设$ans[1][1]$表示区间左端点一定不被选择,右端点可能被选择时的最大值。

对于叶节点,显然$ans[0][0]=ans[0][1]=0$,$ans[1][0]=val[x]$,$ans[1][1]=-INF$。

考虑已经求出$[l,mid]$,$[mid+1,r]$两个区间的答案,如何合并出$[l,r]$的答案。

不难发现$ans[0][0]=max(ansl[0][0]+ansr[0][0],ansl[0][1]+ansr[1][0])$;

$ans[0][1],ans[1][0],ans[1][1]$的转移都长得差不多。

每次修改一个权值,我们可以通过$pushup$更新区间的答案矩阵。

考虑把这个做法扩展到树上,我们通过树链剖分将整棵树剖成若干条链,对于每一条链我们就用如上所述的方式进行维护。对于接有轻儿子的链上节点,我们将轻儿子产生的共吸纳累计,将其加到链上节点上即可。

(细节可以看代码)

时间复杂度:$O(m log^2n)$。

 #include<bits/stdc++.h>
#define ls (x<<1)
#define rs (x<<1|1)
#define mid ((a[x].l+a[x].r)>>1)
#define L long long
#define INF 1000000007
#define M 100005
using namespace std; struct edge{int u,next;}e[M*]={}; int head[M]={},use=;
void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;}
int val[M]={},n,m,f[M][]={}; int siz[M]={},son[M]={},dn[M]={},top[M]={},dfn[M]={},rec[M]={},fa[M]={},t=; void dfs1(int x){
siz[x]=;
for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa[x]){
fa[e[i].u]=x;
dfs1(e[i].u);
siz[x]+=siz[e[i].u];
if(siz[son[x]]<siz[e[i].u]) son[x]=e[i].u;
}
}
void dfs2(int x,int Top){
top[x]=Top; dfn[x]=++t; rec[t]=x;
if(son[x]) dfs2(son[x],Top),dn[x]=dn[son[x]];
else dn[x]=x;
for(int i=head[x];i;i=e[i].next)
if(e[i].u!=fa[x]&&e[i].u!=son[x])
dfs2(e[i].u,e[i].u);
}
void dp(int x,int fa){
f[x][]=val[x];
for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa){
dp(e[i].u,x);
f[x][]+=max(f[e[i].u][],f[e[i].u][]);
f[x][]+=f[e[i].u][];
}
} struct mat{
int a[][]; mat(){memset(a,,sizeof(a));}
mat(int x){a[][]=a[][]=a[][]=a[][]=x;}
mat(int a1,int a2,int a3,int a4){a[][]=a1; a[][]=a2; a[][]=a3; a[][]=a4;}
friend mat operator *(mat a,mat b){
mat c=-INF;
for(int i=;i<;i++)
for(int j=;j<;j++)
for(int k=;k<;k++)
c.a[i][j]=max(c.a[i][j],a.a[i][k]+b.a[k][j]);
return c;
}
}wei[M];
struct seg{int l,r;mat a;}a[M<<];
void pushup(int x){a[x].a=a[ls].a*a[rs].a;} void build(int x,int l,int r){
a[x].l=l; a[x].r=r;
if(l==r){
int u=rec[l],g0=,g1=val[u];
for(int i=head[u];i;i=e[i].next)
if(e[i].u!=son[u]&&e[i].u!=fa[u]){
g0+=max(f[e[i].u][],f[e[i].u][]);
g1+=f[e[i].u][];
}
a[x].a=wei[l]=mat(g0,g0,g1,-INF);
return;
}
build(ls,l,mid);
build(rs,mid+,r);
pushup(x);
}
void updata(int x,int k){
if(a[x].l==a[x].r) return void(a[x].a=wei[k]);
if(k<=mid) updata(ls,k);
else updata(rs,k);
pushup(x);
} mat query(int x,int l,int r){
if(l<=a[x].l&&a[x].r<=r) return a[x].a;
mat res;
if(l<=mid) res=query(ls,l,r);
if(mid<r){
if(l<=mid) return res*query(rs,l,r);
return query(rs,l,r);
}else return res;
}
mat query(int x){return query(,dfn[top[x]],dfn[dn[x]]);}
void solve(){mat hh=query(); printf("%d\n",max(hh.a[][],hh.a[][]));} void Updata(int x,int Val){
wei[dfn[x]].a[][]+=Val-val[x]; val[x]=Val;
while(x){ mat last=query(x);
int lg0=max(last.a[][],last.a[][]),lg1=last.a[][]; updata(,dfn[x]); mat now=query(x);
int ng0=max(now.a[][],now.a[][]),ng1=now.a[][]; x=fa[top[x]]; if(!x) return; int g0=ng0-lg0,g1=ng1-lg1;
wei[dfn[x]].a[][]+=g0;
wei[dfn[x]].a[][]+=g0;
wei[dfn[x]].a[][]+=g1;
}
} int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",val+i);
for(int i=,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfs1();
dfs2(,);
dp(,);
build(,,n);
//solve();
while(m--){
int x,y; scanf("%d%d",&x,&y);
Updata(x,y);
solve();
}
}

【洛谷P4719】动态dp 动态dp模板的更多相关文章

  1. 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)

    洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\)​​​​​.我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...

  2. 洛谷P4719 【模板】"动态 DP"&动态树分治

    [模板]"动态 DP"&动态树分治 第一道动态\(DP\)的题,只会用树剖来做,全局平衡二叉树什么的就以后再学吧 所谓动态\(DP\),就是在原本的\(DP\)求解的问题上 ...

  3. 洛谷p1052过河 路径压缩+dp

    洛谷 P1052 过河 思路部分可以看这篇博客 我将在这里对其进行一些解释与补充 首先我们先看题 乍一看 这不是模板题吗 然后开开心心的敲了一个简单dp上去 #include<iostream& ...

  4. 洛谷2344 奶牛抗议(DP+BIT+离散化)

    洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...

  5. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  6. 洛谷P1541 乌龟棋(四维DP)

    To 洛谷.1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游 ...

  7. 【洛谷】P1052 过河【DP+路径压缩】

    P1052 过河 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙 ...

  8. 【题解】洛谷P1052 [NOIP2005TG] 过河(DP+离散化)

    题目来源:洛谷P1052 思路 一开始觉得是贪心 但是仔细一想不对 是DP 再仔细一看数据不对 有点大 如果直接存下的话 显然会炸 那么就需要考虑离散化 因为一步最大跳10格 那么我们考虑从1到10都 ...

  9. 洛谷1736(二维dp+预处理)

    洛谷1387的进阶版,但很像. 1387要求是“全为1的正方形”,取dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1]))吧?这个有“只有对 ...

  10. bzoj3295 洛谷P3157、1393 动态逆序对——树套树

    题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...

随机推荐

  1. gitlab VS github

    gitlab 和 github的比较 GitLab - 基于Git的项目管理软件 GitLab 是一个用于仓库管理系统的开源项目.使用Git作为代码管理工具,并在此基础上搭建起来的web服务.

  2. Part 1 - Getting Started(1-3)

    https://simpleisbetterthancomplex.com/series/2017/09/04/a-complete-beginners-guide-to-django-part-1. ...

  3. The class cn.itcast.web.common.util.UtilFuns specified in TLD for the function selffn:htmlNewline cannot be found: cn.itcast.web.common.util.UtilFuns

    我的一个Util方法的包名更改了,运行时候报这个错误.找到tld文件,把包名重新改为我改的名字就好使了.

  4. HDU 2095 find your present (2) (异或)

    题意:给定n个数,让你找出那一个次数为1的. 析:由于题意说了,只有那一个数是奇数,所以其他的都是偶数,根据异或的性质,两个相同的数异或为0: 任何数和0异或得原数,可以很简单的做出这个题. 代码如下 ...

  5. Python 正斜杠/与反斜杠\

    首先,"/"左倾斜是正斜杠,"\"右倾斜是反斜杠,可以记为:除号是正斜杠一般来说对于目录分隔符,Unix和Web用正斜杠/,Windows用反斜杠,但是现在Wi ...

  6. 重大发现 springmvc Controller 高级接收参数用法

    1.  数组接收 @RequestMapping(value="deleteRole.json") @ResponseBody public Object deleteRole(S ...

  7. 如何开发一个产品级的Node.js 应用

    介绍 Node.js是一个开源的javascript运行时环境.非常简单可以快速开发一个网络应用.这个平台运行在Linux.OSX和Windows,而且运行在这个平台上的应用都是用javascript ...

  8. Corel Video Studio Pro X5

    视频编辑也是大学的时候接触过,依稀记得转场,字幕,滤镜,电子相册等的概念.自己也不经常用,所以实践经验比较少.正好接一个机会学习一下视频编辑,用的是会声会影X5. 需要的软件Photoshop,格式工 ...

  9. Jersey服务端

    问世间情为何物,直叫人一声呵呵. 上个项目写的jersey restful服务端,怎么都是正确的,没什么问题.结果这个项目写了,呵呵了,真的呵呵了,怎么搞都有问题. 总是报错,对json的类型报错,无 ...

  10. subprocess.Popen 运行windows命令出现“句柄无效”报错的解决方法

    在框架开发中遇到 subprocess执行多了,就会好句柄无效的问题,终于找到解决方案:如下,修改subprocess中的一点代码就好,也不知道这是不是Python 的bug因为,Python27时没 ...