4719 【模板】"动态 DP"&动态树分治 题解
暴力竟然进了第一页!!!
还是一道紫题!!!
我也没懂,我这
思路:
重新计算他的祖先时,不用把每个儿子都算一遍,只需要算这个点有修改过的儿子前后两次的差值。
code time:
/* 西江月·证明
即得易见平凡,仿照上例显然。
留作习题答案略, 读者自证不难。
反之亦然同理,推论自然成立。
略去过程QED,由上可知证毕。*/
#include<set>
#include<map>
#define mod 10
#include<list>
#include<cmath>
#include<queue>
#include<ctime>
#include<stack>
#include<ctime>
#include<bitset>
#include<memory>
#include<cstdio>
#include<string>
#include<sstream>
#include<utility>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rg register
#define bll __int128
#define ll long long
#define inf 214232409
#define ull unsigned long long
#define debug() cout<<"SOSOSOSOSOSOSOS!!!!!!!!!"
#define C(i,j) dp[i+1][j+1]
using namespace std;
int read(){
int ans=0,f=1;char a=getchar();while(a>'9'||a<'0'){if(a=='-')f=(-1);a=getchar();}
while(a>='0'&&a<='9')ans=(ans<<3)+(ans<<1)+a-'0',a=getchar();return ans*f;
}//一条long long的黄金分割线---------------------------------------------------------------------------------------------
int n,m,v[100005],first[100005],cnt,fa[100005],root=1,dp[100005][2],x,y,z,now,now_val;
struct edge{
int to,nxt;
}e[200005];
void add(int x,int y){
e[++cnt].nxt=first[x];
e[cnt].to=y;
first[x]=cnt;
}
void dfs(int now,int f){
fa[now]=f;dp[now][1]=v[now];
for(int i=first[now],v;i;i=e[i].nxt){
v=e[i].to;
if(v==f)continue;
dfs(v,now);
dp[now][0]+=max(dp[v][0],dp[v][1]);
dp[now][1]+=dp[v][0];
}
}//树形dp ,不会可以先去学习一下。
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)v[i]=read();
for(int i=1;i<n;i++)add(read(),read());
dfs(root,-1);
for(int i=1;i<=m;i++){
x=read();y=read();
int fx=dp[x][0],fy=dp[x][1];
dp[x][1]=dp[x][1]-v[x]+y;
int now=fa[x],son=x,ldp0=fx,ldp1=fy;
while(now+1){
int fx=dp[now][0],fy=dp[now][1];
dp[now][0]-=max(ldp0,ldp1)-max(dp[son][0],dp[son][1]);//根据上面dfs的树形dp递推公式统计差值
dp[now][1]-=ldp0-dp[son][0];//同理
son=now,now=fa[now],ldp0=fx,ldp1=fy;//记录当前点,因为无法知道下一个点的儿子,记录当下一个点
//还记录原来dp的值,计算差值
}
v[x]=y;
printf("%d\n",max(dp[root][0],dp[root][1]));//输出dp结果
}
return 0;
}
/*
* ┌───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
* │Esc│ │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│ ┌┐ ┌┐ ┌┐
* └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘ └┘ └┘ └┘
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
* │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │Num│ / │ * │ - │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
* │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │ │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
* │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter │ │ 4 │ 5 │ 6 │ │
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───┐ ├───┼───┼───┼───┤
* │ Shift │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│ Shift │ │ ↑ │ │ 1 │ 2 │ 3 │ │
* ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
* │ Ctrl│ Win│ Alt│ Space │ Alt│ Win│Menu│Ctrl│ │ ← │ ↓ │ → │ │ 0 │ . │←─┘│
* └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
*/