其他分享
首页 > 其他分享> > 【CF1101D】GCD Counting

【CF1101D】GCD Counting

作者:互联网

题目传送门:

  1. https://codeforces.ml/problemset/problem/1101/D
  2. http://u.gdfzoj.com/problem/3501

题意描述:给出一棵\(n\)个节点的树,每个节点上有点权\(a_i\)。求最长的树上路径,满足条件:路径上经过节点(包括两个端点)点权的\(\gcd\)和不等于\(1\)。


首先,我们先明白一件事情:题目要求我们的\(\gcd\)之和不等于\(1\),指的是我们并不关心\(\gcd\)的值是多少,只要它大于\(1\)即可。而\(\gcd\)不是\(1\),意味着一定有公共质因子。

接下来就好办了,我们可以用\(f[x][j]\)表示以\(x\)为根的子树往下走,公共质因子为\(j\)的最大值

又因为不同的质因子个数十分少,所以几乎可以看成一个常数,可以暴力处理每一个节点的信息。显然最优解一定会被处理到。


代码:

#include<bits/stdc++.h>
namespace Bu_Yao_Tian_Tian_Bi_Sai {
	using namespace std;
#define LL long long
	inline LL read() {
		char c=getchar();
		LL sum=0;
		while(c<'0'||c>'9') {
			c=getchar();
		}
		while(c>='0'&&c<='9') {
			sum=(sum<<3)-'0'+(sum<<1)+c,c=getchar();
		}
		return sum;
	}
	inline void write(LL x) {
		if(x>9) {
			write(x/10);
		}
		putchar(x%10+'0');
	}
	const int d[4][2]= {
		{1,0},{0,1},{-1,0},{0,-1}
	},mod=1e9+7,N=1e6+5;
}
using namespace Bu_Yao_Tian_Tian_Bi_Sai;
struct edge {
	int to,nxt;
} e[N<<1];
int head[N],cnt,ans=1;
inline void add(int u,int v) {
	e[++cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;
}
vector<int> p[N],f[N];
//p[u]:对u分解质因数后的结果
//f[u][v]:u为根的子树,往下走,公共质因子为v的最长链
int max(int u,int v) {
	return u<v?v:u;
}
void dfs(int u,int fa) {
	for(int i=head[u]; i; i=e[i].nxt) {
		int v=e[i].to;
		if(v==fa) {
			continue ;
		}
		dfs(v,u);
		for(int j=0; j<p[u].size(); j++) {
			for(int k=0; k<p[v].size(); k++) {
				if(p[u][j]==p[v][k]) {
					ans=max(ans,f[u][j]+f[v][k]);//连接两条路径
					f[u][j]=max(f[u][j],f[v][k]+1);
				}
			}
		}
	}
}
void fen(int x,int tmp) {
	for(int i=2; i*i<=x; i++) {
		if(x%i==0) {
			p[tmp].push_back(i),f[tmp].push_back(1);
			while(x%i==0) {
				x/=i;
			}
		}
	}
	if(x>1) {
		p[tmp].push_back(x),f[tmp].push_back(1);
	}
}
int main() {
	int n=read();
	bool flag=0;
	for(int i=1,x; i<=n; i++) {
		x=read();
		if(x^1) {
			flag=1;
		}
		fen(x,i);
	}
	if(!flag) {
		write(0);
		return 0;
	}
	for(int i=1,u,v; i<n; i++) {
		u=read(),v=read(),add(u,v),add(v,u);
	}
	dfs(1,0);
	write(ans);
	return 0;
}
/*
  _  __
 (_)/   \
<'_, ____)~~~~~~~
  ^^   ^^
*/

完美撒花~

标签:gcd,CF1101D,int,LL,namespace,Tian,Counting,节点,GCD
来源: https://www.cnblogs.com/Sam2007/p/12625607.html