2 条题解

  • 0
    @ 2025-10-8 16:59:16
    #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
      @ 2025-10-8 16:59:10
      #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
      上传者