动态动态规划 DDP
luckydrawbox · · 个人记录
宏定义
同树链剖分。
变量
函数
代码
#define pl p<<1
#define pr p<<1|1
#define pf a[p].fa
#define pde a[p].dep
#define psi a[p].sze
#define pte a[p].ted
#define pdf a[p].dfn
#define pso a[p].son
#define pt a[p].top
#define pc a[p].ced
const long long inf=1e9;
struct Juz{
long long a[3][3],h,l;
void clean(){
memset(a,-0x3F,sizeof a);
h=l=0;
}
}w[N];
Juz operator *(const Juz &x,const Juz &y){
Juz z;
z.clean();
z.h=x.h;z.l=y.l;
for(int i=1;i<=x.h;++i)
for(int j=1;j<=y.l;++j)
for(int k=1;k<=x.l;++k)
z.a[i][j]=max(z.a[i][j],x.a[i][k]+y.a[k][j]);
return z;
}
int f[N][2],dq[N];
struct Segment_Tree{
struct Tree{
int l,r;
Juz val;
}a[N*4];
void pushup(int p){
a[p].val=a[pl].val*a[pr].val;
}
void build(int p,int l,int r,int *rnk){
a[p].l=l;
a[p].r=r;
if(l==r){
a[p].val=w[rnk[l]];
return;
}
int mid=(l+r)>>1;
build(pl,l,mid,rnk);
build(pr,mid+1,r,rnk);
pushup(p);
}
void change(int p,int x,int *rnk){
if(a[p].l==a[p].r){
a[p].val=w[rnk[x]];
return;
}
int mid=(a[p].l+a[p].r)>>1;
if(x<=mid)
change(pl,x,rnk);
if(x>mid)
change(pr,x,rnk);
pushup(p);
}
Juz ask(int p,int l,int r){
if(l<=a[p].l&&a[p].r<=r){
return a[p].val;
}
int mid=(a[p].l+a[p].r)>>1;
if(l<=mid&&r>mid)
return ask(pl,l,r)*ask(pr,l,r);
if(l<=mid)
return ask(pl,l,r);
if(r>mid)
return ask(pr,l,r);
}
}tree;
struct TCP{
struct Node{
int fa,dep,dfn;//self
int sze,ted;//tree
int son,top,ced;//chain
}a[N];
int cnt,rnk[N];
void dfs1(int p){
pso=-1;
psi=1;
for(int i=head[p];i;i=nxt[i]){
int y=ver[i];
if(!a[y].dep){
a[y].dep=pde+1;
a[y].fa=p;
dfs1(y);
psi+=a[y].sze;
if(pso==-1||a[y].sze>a[pso].sze)
pso=y;
}
}
}
int dfs2(int p,int q){
pt=q;
pdf=++cnt;
rnk[cnt]=pte=p;
/*make*/
f[p][0]=0;f[p][1]=dq[p];
w[p].h=w[p].l=2;
w[p].a[1][1]=w[p].a[1][2]=0;
w[p].a[2][1]=dq[p];
bool yu=0;
if(pso==-1){
int ted=pte;
pc=cnt;
while(p!=q){
p=pf;
pc=cnt;
}
yu=1;
return ted;
}
pte=dfs2(pso,q);
/*update*/
f[p][0]+=max(f[pso][0],f[pso][1]);
f[p][1]+=f[pso][0];
for(int i=head[p];i;i=nxt[i]){
int y=ver[i];
if(y==pso||y==pf)
continue;
pte=dfs2(y,y);
/*update*/
f[p][0]+=max(f[y][0],f[y][1]);
f[p][1]+=f[y][0];
w[p].a[1][1]+=max(f[y][0],f[y][1]);
w[p].a[1][2]=w[p].a[1][1];
w[p].a[2][1]+=f[y][0];
}
return pte;
}
void init(int root,int n){
cnt=0;
a[root].dep=1;
dfs1(root);
dfs2(root,root);
tree.build(1,1,n,rnk);
}
void change1(int p,int z){
w[p].a[2][1]+=z-dq[p];
dq[p]=z;
Juz x,y;
while(p){
x=tree.ask(1,a[pt].dfn,pc);
tree.change(1,pdf,rnk);
y=tree.ask(1,a[pt].dfn,pc);
p=pt;p=pf;
/*merge*/
w[p].a[1][1]+=max(y.a[1][1],y.a[2][1])-max(x.a[1][1],x.a[2][1]);
w[p].a[1][2]=w[p].a[1][1];
w[p].a[2][1]+=y.a[1][1]-x.a[1][1];
}
}
int ask1(){
Juz an=tree.ask(1,1,a[1].ced);
return max(an.a[1][1],an.a[2][1]);
}
}tr;