C - Ilya And The Tree CodeForces - 842C (纪念一下set的用法)
题意:给出一棵生成树,每个节点都有一个值,现在要求出每个节点的美丽值的最大值,美丽值的定义为从根节点到该节点(包含)路径上所有点的值的gcd,求解每个点时可以把路径上某一个点的值变为0。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<set>
using namespace std;
const int maxn=2*1e5+10;
//求gcd
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
vector<int> v[maxn];//边
int val[maxn];//值
bool vis[maxn];
set<int> s[maxn];
void dfs(int u,int f,int g){
//cout<<u<<endl;
s[u].insert(gcd(g,val[u]));
s[u].insert(g);
for(set<int>::iterator it=s[f].begin();it!=s[f].end();it++){
int t=*it;
s[u].insert(gcd(t,val[u]));
}
g=gcd(g,val[u]);//
for(int i=0;i<v[u].size();i++) {
int x=v[u][i];
if(!vis[x]){
vis[x]=1;
dfs(x,u,g);
}
}
return;
}
int main(){
int n,a,b;
//cout<<gcd(10,0)<<endl;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
for(int i=0;i<n-1;i++){
scanf("%d%d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
memset(vis,0,sizeof(vis));
vis[1]=1;
dfs(1,0,0);
for(int i=1;i<=n;i++){
if(i==1) printf("%d",*s[i].rbegin());
else printf(" %d",*s[i].rbegin());
}
printf("\n");
return 0;
}