如题,题目是 CF2065F。
这是 record。
我的代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+9;
bool ans[N],cl[N];
int n,m,T,a[N];
vector<int>q[N];
void dfs(int now,int fa=0){
cl[a[now]]=1;
for(auto i:q[now]){
if(cl[a[i]]) ans[a[i]]=1;
cl[a[i]]=1;
}
cl[a[now]]=0;
for(auto i:q[now]) cl[a[i]]=0;
for(auto i:q[now]) if(i!=fa) dfs(i,now);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++) q[i].clear(),ans[i]=0,scanf("%d",&a[i]);
int u,v;
for(int i=1;i<n;i++) scanf("%d %d",&u,&v),q[u].push_back(v),q[v].push_back(u);
dfs(1);
for(int i=1;i<=n;i++) printf("%d",ans[i]);
putchar('\n');
}
return 0;
}
显然,调用 dfs(1) 至多会递归 n 次,搜 2n 条边,所以复杂度是严格 O(∑n) 的,但是常数较大。
而题面中有这样一句话:
题目保证给定的边构成一棵树,并且所有测试用例中 n 的总和不超过 5⋅105。
因此这份代码算上常数,应该至多运算 107 次,但是却跑了 1.3 秒,求问一下为什么是这样的?