蒟蒻bfs求调
查看原帖
蒟蒻bfs求调
765185
Tenil楼主2024/8/15 17:15

思路:记录每个点的梅花数ww、最左儿子lsls、最右儿子rsrs、编号nn、父节点ff、子节点的最大放置费用mwmw、子节点维护费用fwfw,从叶子节点开始搜,一个节点的子节点全搜完后把它当作叶子继续搜,最后到根(类似拓扑排序),感觉是没问题的,样例全过,交测评只能过一个。

#include <iostream>
#include <cstdio>
#include <queue>
#define fo(i,x,y,k) for(register int i = x; k*i < k*y; i+=k)

using namespace std;

const int maxn=1e5+4;

long long ans[maxn];
int n;

struct po{
	int f=0,ls=0x3f3f3f,rs=-1,n,w,cnt=0;
	long long mw=0,fw=0;
}p[maxn];

queue<po> ps;

int fr() {
	int x=0;char c=getchar();
	while(c<'0'||c>'9'){
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=(x<<3)+(x<<1)+(c^48);
		c=getchar();
	}
	return x;
}

inline long long _max(long long x,long long y) {
	return (x>y) ? x : y;
}

inline void upd(int x) {
	int f = p[x].f;
	ans[f]+=p[x].w;
	p[f].cnt++;
	if(p[f].cnt==p[f].rs-p[f].ls+1||f==0) {
		p[f].mw=_max(p[f].mw,ans[x]);
		ans[f]+=p[f].w;
		ans[f]=_max(ans[f],p[f].mw)+p[f].fw;
		if(f) ps.push(p[f]);
	}
	else {
		ans[f]-=p[x].w;
		p[f].mw=_max(p[f].mw,ans[x]);
		p[f].fw+=p[x].w;
	}
	return;
}

int main() {
	n=fr();
	int x;
	fo(i,1,n,1) {
		x=fr();
		p[i+1].f=x;
		if(p[x].ls>i+1) p[x].ls=i+1;
		if(p[x].rs<i+1) p[x].rs=i+1;
	}
	fo(i,1,n+1,1) {
		x=fr();
		p[i].w=x;
		p[i].n=i;
		if(p[i].rs==-1&&p[i].ls==0x3f3f3f) {
			ans[i]=x;
			ps.push(p[i]);
		}
	}
	po p1;
	while(!ps.empty()){
		p1=ps.front();
		ps.pop();
		upd(p1.n);
	}
	fo(i,1,n+1,1) {
		printf("%lld ",ans[i]);
	}
	return 0;
}
2024/8/15 17:15
加载中...