AC后的两个问题
查看原帖
AC后的两个问题
1124323
A_small_WA楼主2025/2/6 20:52

1:我感觉这题的复杂度是假的。

2:我感觉我的编译器是假的。

AC代码如下(而且可以看到跑得飞快

#include <bits/stdc++.h>
using namespace std;
const int N=100020;
int up[N][30],all[N][30],p[N],n,k;
vector <int> vt[N];
void find_up(int x,int fa){
	for(int i=0;i<vt[x].size();i++){
		int w=vt[x][i];
		if(w==fa) continue;
		find_up(w,x);
		for(int i=1;i<=k;i++) 
			up[x][i]+=up[w][i-1];
	}
	for(int i=0;i<=k;i++) up[x][i]+=p[x],all[x][i]=up[x][i];
}
void find_all(int x,int fa){
	if(fa!=-1){
		for(int i=1;i<=k;i++)
			all[x][i]+=all[fa][i-1]-up[x][i-2];
	}
	for(int i=0;i<vt[x].size();i++){
		int w=vt[x][i];
		if(w==fa) continue;
		find_all(w,x);
	}
}
int main(){
	int u,v,ans=0;
	cin>>n>>k;
	for(int i=1;i<n;i++){
		cin>>u>>v;
		vt[u].push_back(v);
		vt[v].push_back(u);
	}
	for(int i=1;i<=n;i++) cin>>p[i];
	find_up(1,-1);
	find_all(1,-1);
	for(int i=1;i<=n;i++) cout<<all[i][k]<<'\n';
	return 0;
}

但是在 find_up 函数中,对于每一个节点 x,连接它的每一条边都会被遍历一次,且遍历的同时还会有一个 k 次的 for 循环。

那是不是说这个代码的复杂度就是 O(nk)O(nk)

如果是的,那为什么暴力不能过?(从每一个节点延伸 kk 次也是 O(nk)O(nk) 的呀)如果蒟蒻的理解有误,请大佬们轻喷。

其次,在 find_up 函数中的 for 循环嵌套中两层循环变量都用的是 i,一般来说编译器不是应该给个 Warning 什么之类的吗,但这次什么都没提示,等我交完才发现。难道又是什么隐藏bug?

2025/2/6 20:52
加载中...