ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luoguP4719 【模板】动态 DP 线段树_树链剖分_矩阵乘法_动态DP

2019-06-03 09:53:17  阅读:208  来源: 互联网

标签:tmp hson 剖分 int bot mid dfn 动态 DP


Code:

#include<bits/stdc++.h> 
#define setIO(s) freopen(s".in","r",stdin) 
#define maxn 300000 
#define lson (now<<1) 
#define rson ((now<<1)|1) 
#define ll long long 
const ll inf = 1e17; 
using namespace std;
int hd[maxn],to[maxn],nex[maxn],V[maxn],hson[maxn],fa[maxn],dfn[maxn], ln[maxn],F[maxn][2],siz[maxn],top[maxn],bot[maxn]; 
int edges,tim,n,Q; 
void add(int u,int v)
{
	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
}
void dfs1(int u,int ff)
{
	siz[u]=1,fa[u]=ff; 
	for(int i=hd[u];i;i=nex[i])
	{
		if(to[i]==ff) continue; 
		dfs1(to[i],u); 
		siz[u]+=siz[to[i]]; 
		if(siz[to[i]] > siz[hson[u]]) hson[u]=to[i]; 
	}
}
void dfs2(int u,int tp)
{
	top[u]=tp,ln[++tim]=u,dfn[u]=tim; 
	if(hson[u]) 
		dfs2(hson[u], tp), bot[u]=bot[hson[u]]; 
	else 
		bot[u]=u; 
	for(int i=hd[u];i;i=nex[i])
	{
		if(to[i]==fa[u]||to[i]==hson[u]) continue; 
		dfs2(to[i],to[i]);  
	}
}
void dfs(int u)
{
	F[u][0]=0,F[u][1]=V[u]; 
	for(int i=hd[u];i;i=nex[i])
	{
		if(to[i]==fa[u]) continue; 
		dfs(to[i]); 
		F[u][0]+=max(F[to[i]][1],F[to[i]][0]); 
		F[u][1]+=F[to[i]][0]; 
	}
}
struct Matrix
{
	ll a[2][2]; 
	ll*operator[](int x){ return a[x]; }
}t[maxn<<1],tmp[maxn<<1]; 
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; 
}
void Build(int now,int l,int r)
{
	if(l==r)
	{
		int u=ln[l];  
		ll g0=0,g1=V[u]; 
		for(int i=hd[u];i;i=nex[i])
		{
			int v=to[i];
			if(v==fa[u]||v==hson[u]) continue; 
			g0+=max(F[v][0],F[v][1]); 
			g1+=F[v][0]; 
		}
		t[now]=tmp[l]=(Matrix) {g0,g0,g1,-inf}; 
		return; 
	}
	int mid=(l+r)>>1; 
	Build(lson,l,mid),Build(rson,mid+1,r); 
	t[now]=t[lson]*t[rson]; 
}
void Modify(int now,int l,int r,int p)
{
	if(l==r) 
	{
	    t[now]=tmp[l]; 
	    return;  
	}
	int mid=(l+r)>>1; 
	if(p<=mid) Modify(lson,l,mid,p); 
	else Modify(rson,mid+1,r,p); 
	t[now]=t[lson]*t[rson]; 
}
Matrix Query(int now,int l,int r,int L,int R)
{
	if(L==l&&r==R) return t[now];
	int mid=(l+r)>>1; 
	if(R<=mid) return Query(lson,l,mid,L,R); 
	if(L>mid) return Query(rson,mid+1,r,L,R); 
	return Query(lson,l,mid,L,mid)*Query(rson,mid+1,r,mid+1,R); 
}
void Update(int u,int w)
{
	tmp[dfn[u]][1][0]+=w-V[u],V[u]=w; 
	while(u)
	{
		Matrix a=Query(1,1,n,dfn[top[u]],dfn[bot[u]]); 
		Modify(1,1,n,dfn[u]); 
		Matrix b=Query(1,1,n,dfn[top[u]],dfn[bot[u]]); 
		u=fa[top[u]];
		if(!u) break; 
		int x = dfn[u]; 
		ll g0=a[0][0],g1=a[1][0],f0=b[0][0],f1=b[1][0]; 
		tmp[x][0][0]=tmp[x][0][1]=tmp[x][0][0]+max(f0,f1)-max(g0,g1); 
		tmp[x][1][0]=tmp[x][1][0]+f0-g0; 
	}
}
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); 
	}
	dfs1(1,0),dfs2(1,1),dfs(1),Build(1,1,n); 
	while(Q--)
	{
		int x,w; 
		scanf("%d%d",&x,&w);
		Update(x,w); 
		Matrix ans=Query(1,1,n,dfn[1],dfn[bot[1]]);                
		printf("%lld\n",max(ans[0][0],ans[1][0])); 
	}
	return 0; 
}

  

标签:tmp,hson,剖分,int,bot,mid,dfn,动态,DP
来源: https://www.cnblogs.com/guangheli/p/10965885.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有