动态 dp 求助
查看原帖
动态 dp 求助
237530
rzh123楼主2023/1/16 23:55

样例过不了

#include <bits/stdc++.h>
#define gc IO::fastgc()
#define pc(c) IO::fastpc(c)
#define printf(x...)
typedef long long ll;typedef long long unsigned llu,ull;typedef long double lf;
using namespace std;
namespace IO{char ibuf[1<<23],obuf[1<<23],*ip1=ibuf,*ip2=ibuf,*o=obuf;inline char fastgc(){return((ip1==ip2)&&(ip2=(ip1=ibuf)+fread(ibuf,1,1<<21,stdin),ip1==ip2)?EOF:*ip1++);}inline void fastpc(char c){(o-obuf<(1<<22))?(*(o++)=c):(fwrite(obuf,o-obuf,1,stdout),o=obuf,*(o++)=c);}struct _{_(){}~_(){fwrite(obuf,o-obuf,1,stdout);}}__;}
template<typename T>inline void read(T &t){t=0;T f=1;char c=gc;while(c!='-'&&(c<'0'||c>'9'))c=gc;if(c=='-')f=-1,c=gc;while(c>='0'&&c<='9')t=10*t+(c&15),c=gc;t*=f;}
template<> inline void read<string>(string &t){t="";char c=gc;while(isspace(c)||c==EOF)c=gc;while(!(isspace(c)||c==EOF))t+=c,c=gc;}
template<> inline void read<char>(char&t){t=gc;while(t==' '||t=='\r'||t=='\t'||t=='\n')t=gc;}
template<typename T>inline void write(T x){if(!x)return(void)pc('0');if(x<0)pc('-'),x=-x;static char c[33]={""};static int cc=0;while(x)c[++cc]=x%10,x/=10;while(cc)pc(c[cc--]|48);}
inline void write(const string &x){for(auto c:x)pc(c);}
inline void write(const char *x){for(;*x;++x)pc(*x);}
inline void write(char _){pc(_);}
template<typename T1,typename ...Args> inline void read(T1 &v1,Args&... args){read(v1),read(args...);}
template<typename T1,typename ...Args> inline void write(const T1 &v1,const Args&... args){write(v1),write(args...);}

/*
	普通 dp:
		f[u][j]=u点 有/没有 驻扎,子树最小花费 
		f[u][0]=sum(f[v][1])
		f[u][1]=p[u]+sum(max(f[v][0],f[v][1]))
	动态 dp: 
		f[u][j]表示所有点的dp 
		g[u][j]表示u的子结点中轻链的dp 
		f[u][0]=g[u][0]+f[hs][1]
		f[u][1]=g[u][1]+max(f[hs][0],f[hs][1])
		fi0	=	INF gi0	*	fhs0
		fi1		gi1 gi1		fhs1
	代码中的g[u]用h[u]表示 
*/ 
constexpr unsigned N=1e5+7,NN=4e5+37,M=2e5+17;
constexpr int INF=0x3f3f3f4f;
int n,m;
vector<int> g[N];
string datatype;
int fa[N],dep[N],sz[N],hs[N],dfn[N],tp[N],ed[N],pos[N],dft;
int f[N][2],h[N][2],p[N];
int htmp[N][2];
struct Matrix{
	int a[2][2];
	inline void zero(){a[0][0]=a[0][1]=a[1][0]=a[1][1]=INF;}
	inline void unit(){a[0][0]=a[1][1]=0,a[0][1]=a[1][0]=INF;} 
	inline int *operator[](unsigned i){return a[i];}
	inline const int *operator[](unsigned j)const{return a[j];}
	inline Matrix operator*(const Matrix &b)const{
		Matrix c;
		c.zero();
		for(int k{0};k<2;++k)
			for(int i{0};i<2;++i)
				for(int j{0};j<2;++j)
					c[i][j]=min(c[i][j],a[i][k]+b[k][j]);
		return c;
	}
};
inline void out(const Matrix &x){
	printf("[%d,%d,%d,%d]\n",x[0][0],x[0][1],x[1][0],x[1][1]);
}
struct{
	struct{
		int l,r;
		Matrix x;
	}tr[NN];
	inline void apply(int k,int u){
		auto &m=tr[k].x;
		m.zero(),
		m[0][1]=h[u][0],
		m[1][0]=m[1][1]=h[u][1];
	}
	inline void pushup(int k){
		tr[k].x=tr[k<<1].x*tr[k<<1|1].x;
	}
	void build(int k,int l,int r){
		printf("%d:%d,%d\n",k,l,r);
		tr[k].l=l,tr[k].r=r;
		if(l==r){
			printf("l=%d(%d)\n",l,pos[l]);
			apply(k,pos[l]);
			printf("m[%d]=",k);out(tr[k].x);
			return;
		}
		int m{(l+r)>>1};
		build(k<<1,l,m),
		build(k<<1|1,m+1,r),
		pushup(k);
		printf("m [%d]=",k);out(tr[k].x);
	}
	void modify(int k,int x){
		if(tr[k].l>x||tr[k].r<x) return;
		if(tr[k].l==tr[k].r) return apply(k,pos[x]);
		modify(k<<1,x),modify(k<<1|1,x),
		pushup(k);
	}
	Matrix query(int k,int l,int r){
		Matrix ret;
		ret.unit();
		if(tr[k].l>r||tr[k].r<l) return ret;
		if(tr[k].l>=l&&tr[k].r<=r) return tr[k].x;
		return query(k<<1,l,r)*query(k<<1|1,l,r);
	}
}seg;
void dfs(int u,int fa){
	::fa[u]=fa,
	dep[u]=dep[fa]+1,
	sz[u]=1;
	for(auto v:g[u]){
		if(v==fa) continue;
		dfs(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[hs[u]]){
			hs[u]=v;
		}
	}
}
void sfd(int u,int fa,int tpn){
	pos[dfn[u]=++dft]=u;
	tp[u]=tpn;
	ed[tpn]=max(ed[tpn],dft);
	if(hs[u]){
		sfd(hs[u],u,tpn);
	}
	for(auto v:g[u]){
		if(v==fa||v==hs[u]) continue;
		sfd(v,u,v);
	}
}
void sdf(int u,int fa){
	printf("sdf(%d,%d)\n",u,fa);
	f[u][0]=h[u][0]=0,
	f[u][1]=h[u][1]=p[u];
	if(hs[u]){
		int v=hs[u];
		sdf(v,u);
		f[u][0]+=f[v][1];
		f[u][1]+=min(f[v][0],f[v][1]);
	}
	for(auto v:g[u]){
		if(v==fa||v==hs[u]) continue;
		printf("v=%d\n",v);
		sdf(v,u);
		f[u][0]+=f[v][1],
		f[u][1]+=min(f[v][0],f[v][1]),
		h[u][0]+=f[v][1],
		h[u][1]+=min(f[v][0],f[v][1]);
	}
	printf("f[%d]={%d,%d},g[%d]={%d,%d}\n",u,f[u][0],f[u][1],u,h[u][0],h[u][1]);
}
inline void modify(int u,int v){
	switch(v){
		case -1:{
			//-1代表恢复 
			h[u][0]=htmp[u][0],
			h[u][1]=htmp[u][1];
			break;
		}
		case 0:{
			h[u][1]=INF;
			break;
		}
		case 1:{
			h[u][0]=INF;
			break;
		}
	}
	Matrix a,b;
	while(u){
		a=seg.query(1,dfn[tp[u]],ed[tp[u]]);
		seg.modify(1,dfn[u]);
		b=seg.query(1,dfn[tp[u]],ed[tp[u]]);
		u=fa[tp[u]];
		h[u][0]+=max(b[0][0],b[1][0])-max(a[0][0],a[1][0]);
		h[u][1]+=b[0][0]-a[0][0];
	}
}
inline int query(){
	Matrix x=seg.query(1,dfn[1],ed[1]);
	int t=min(x[0][0],x[1][0]);
	if(t==INF) return -1;
	return t;
}
signed main(){
	read(n,m,datatype);
	(void)datatype;
	for(int i{1};i<=n;++i){
		read(p[i]);
	}
	for(int i{1};i<n;++i){
		int u,v;
		read(u,v);
		g[u].emplace_back(v),
		g[v].emplace_back(u);
	}
	dfs(1,0),
	sfd(1,0,1),
	sdf(1,0);
	memcpy(htmp,h,sizeof h);
	seg.build(1,1,dft);
	printf("dfa\n");
	printf("%d %d\n",min(f[1][0],f[1][1]),query());
	while(m--){
		int a,x,b,y;
		read(a,x,b,y);
		modify(a,x);
		modify(b,y);
		write(query(),'\n');
		modify(a,-1),
		modify(b,-1); 
	}
	return 0;
}

题解里甚至没有同样写法的

2023/1/16 23:55
加载中...