社区讨论

关于复杂度

P14823[ICPC 2023 Yokohama R] Do It Yourself?参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mkjr8pvh
此快照首次捕获于
2026/01/18 21:11
上个月
此快照最后确认于
2026/01/22 17:55
4 周前
查看原帖
我采用的是堆的启发式合并,代码中用注释描述出的这段部分分析不出来
我看题解中好像也都有这段代码,但是并没有给出相应的分析
CPP
#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int MAXN=5e5+5;

int n;
ll val[MAXN],cnt[MAXN];
vector<int> son[MAXN];
ll sum=0;
priority_queue<ll> q[MAXN];
int idx[MAXN];

int merge(int x,int y){
	if(x==y) return x;
	x=idx[x],y=idx[y];
	if(q[x].size()<q[y].size()) swap(x,y);
	while(!q[y].empty()){
		q[x].push(q[y].top());
		q[y].pop();
	}
	return x;
}//

void dfs(int u){
	for(int v:son[u]){
		dfs(v);
		idx[u]=merge(u,v);
	}
	q[idx[u]].push(val[u]*(2*cnt[u]+1));
	sum+=val[u]*(2*cnt[u]+1);
	++cnt[u];
        //------------以下有疑义
	while(!q[idx[u]].empty() && q[idx[u]].top()>val[u]*(2*cnt[u]+1)){
		sum+=val[u]*(2*cnt[u]+1)-q[idx[u]].top();
		q[idx[u]].pop();
		q[idx[u]].push(val[u]*(2*cnt[u]+1));
		++cnt[u];
	}
}//

int main(){
	scanf("%d",&n);
	for(int i=2,x;i<=n;++i){
		scanf("%d",&x);
		son[x].push_back(i);
	}
	for(int i=1;i<=n;++i) scanf("%lld",&val[i]),idx[i]=i;
	dfs(1);
	printf("%lld",sum);
	return 0;
} 

回复

1 条回复,欢迎继续交流。

正在加载回复...