题面 设f[i]表示根为i的子树改了0\1条边的权值为0时的GCD最大值,记忆化搜索+不正确剪枝(最多搜向上推10层) Code: /* CF842C Ilya And The Tree *//* Developed By WYCTSTF *//* 迎难而上 */#includebits
题面
设f[i]表示根为i的子树改了0\1条边的权值为0时的GCD最大值,记忆化搜索+不正确剪枝(最多搜向上推10层)
Code:
/* CF842C Ilya And The Tree */ /* Developed By WYCTSTF */ /* 迎难而上 */ #include<bits/stdc++.h> #define int long long using namespace std; const int maxn=2e5+10; int a[maxn]; int f[maxn],g[maxn],fat[maxn]; vector <int> e[maxn]; int read(){ int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) f=(ch=='-')?-1:1,ch=getchar(); while(isdigit(ch)) x=x*10+(ch-'0'),ch=getchar(); return x*f; } int gcd(const int &a,const int &b){ return (b==0)?a:gcd(b,a%b); } void getf(int u,int fa){ if(fa==0) g[u]=a[u]; else g[u]=gcd(a[u],g[fa]); if(fa!=0){ f[u]=g[u]; f[u]=max(g[fa],gcd(f[fa],a[u])); int v=fa,gg=a[u],i=10; while(v&&i>0){ f[u]=max(f[u],gcd(gg,f[v])); if(fat[v]!=0){ f[u]=max(f[u],gcd(gg,g[fat[v]])); } else{ f[u]=max(f[u],gg); } gg=gcd(gg,a[v]); v=fat[v]; --i; } } else{ f[u]=g[u]; } int v,i,us=e[u].size(); for (int i=0;i<us;i++){ v=e[u][i]; if(v!=fa&&v!=0){ fat[v]=u; getf(v,u); } } } signed main(){ int n; n=read(); for(int i=1;i<=n;i++) a[i]=read(); int x,y; for(int i=1;i<n;i++){ x=read(),y=read(); e[x].push_back(y),e[y].push_back(x); } getf(1,0); for (int i=1;i<=n;i++){ cout<<max(f[i],g[i]); if(i<n){ cout<<' '; } else puts(""); } return 0; } /* 记忆化搜索+不正确剪枝水过 */