2 条题解
-
0
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=1e5+10; LL a[N], ans, c[N]; vector<int> G[N]; //c[i]表示当前以i为因子的点的个数 void add(LL x){ for(LL i=1; i*i<=x; i++) if(x%i==0){ if(i*i!=x) c[i]++; //平方数不重复加 c[x/i]++; } } void dfs(int x, int fa){ LL pre=c[a[x]]; //pre表示在x的子树之前的累计 add(a[x]); //把a[x]放进去 //当前递归x是找以x为lca的点对个数 for(int y: G[x]) if(y!=fa){ LL t=c[a[x]]; //t表示在y的子树之前的累计 dfs(y, x); ans+=(c[a[x]]-t)*(t-pre); //加上y的子树的累计乘以在y之前x的子树的累计 } } int main(){ //freopen("a.in", "r", stdin); int n; scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%lld", &a[i]); for(int i=1; i<n; i++){ int x, y; scanf("%d%d", &x, &y); G[x].push_back(y); G[y].push_back(x); } memset(c, 0, sizeof(c)); ans=0; dfs(1, 0); printf("%lld\n", ans*2+n); //乘上xy重复的加上xy相同的 return 0; } -
0
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=1e5+10; LL a[N], ans, c[N]; vector<int> G[N]; //c[i]表示当前以i为因子的点的个数 void add(LL x){ for(LL i=1; i*i<=x; i++) if(x%i==0){ if(i*i!=x) c[i]++; //平方数不重复加 c[x/i]++; } } void dfs(int x, int fa){ LL pre=c[a[x]]; //pre表示在x的子树之前的累计 add(a[x]); //把a[x]放进去 //当前递归x是找以x为lca的点对个数 for(int y: G[x]) if(y!=fa){ LL t=c[a[x]]; //t表示在y的子树之前的累计 dfs(y, x); ans+=(c[a[x]]-t)*(t-pre); //加上y的子树的累计乘以在y之前x的子树的累计 } } int main(){ //freopen("a.in", "r", stdin); int n; scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%lld", &a[i]); for(int i=1; i<n; i++){ int x, y; scanf("%d%d", &x, &y); G[x].push_back(y); G[y].push_back(x); } memset(c, 0, sizeof(c)); ans=0; dfs(1, 0); printf("%lld\n", ans*2+n); //乘上xy重复的加上xy相同的 return 0; }
- 1
信息
- ID
- 1907
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 8
- 标签
- 递交数
- 16
- 已通过
- 6
- 上传者