zoukankan      html  css  js  c++  java
  • Edu Codeforces Round 45 选做

    Problem G. GCD Counting

    考虑差分,记录每一个答案 (ans_i)(gcd)(i) 的倍数的方案总数。

    每次只需要枚举出连通块,然后直接计算即可。

    时间复杂度 (O(nsqrt n))

    #pragma GCC optimze("O2")
    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    template <typename T> 
    void read(T& x) {
      x = 0; 
      char ch = 0;
      for (; !isdigit(ch); ch = getchar());
      for (; isdigit(ch); ch = getchar()) {
        x = x * 10 + (ch & 15);
      }
    }
    
    const int N = 2e5 + 5;
    
    struct edge {
      int to, nxt;
    } e[N << 1];
    
    int head[N];
    int edge_cnt;
    int a[N];
    vector<int> fac[N];
    int vis[N];
    long long ans[N];
    int sz, dg;
    
    void add_edge(int u, int v) {
      e[++edge_cnt] = (edge){v, head[u]};
      head[u] = edge_cnt; 
    }
    
    void divide(int x, int id) {
      for (int i = 1; i * i <= x; ++i) {
        if (x % i == 0) {
          fac[i].emplace_back(id); 
          if (i * i != x) {
            fac[x / i].emplace_back(id); 
          }
        }
      }
    }
    
    void dfs(int u, int fa) {
      ++sz;
      vis[u] = dg; 
      for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if (v != fa && a[v] % dg == 0) {
          dfs(v, u); 
        }
      }
    }
    
    int main() {
      int n;
      read(n); 
      for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        divide(a[i], i); 
      }
      for (int i = 1; i < n; ++i) {
        int u, v;
        read(u), read(v); 
        add_edge(u, v); 
        add_edge(v, u); 
      }
      for (dg = 1; dg <= 200000; ++dg) { 
        for (int i = 0, m = fac[dg].size(); i < m; ++i) {
          if (vis[fac[dg][i]] != dg) { 
            sz = 0; 
            dfs(fac[dg][i], 0); 
            ans[dg] += (long long)sz * (sz - 1) / 2 + sz;
          }
        }
      }
      for (int i = 200000; i >= 1; --i) {
        for (int j = i + i; j <= 200000; j += i) {
          ans[i] -= ans[j]; 
        }
      }
      for (int i = 1; i <= 200000; ++i) {
        if (ans[i]) {
          printf("%d %I64d
    ", i, ans[i]); 
        }
      }
      return 0; 
    }
    
  • 相关阅读:
    mariadb配置双主多从
    mq系列rabbitmq-02集群+高可用配置
    mq系列rabbitmq-01简介,安装,api操作
    持续集成框架jenkins介绍02-持久集成git仓库+maven项目
    git仓库相关知识03-搭建远程仓库服务器
    RecyclerView瀑布流优化方案探讨
    Android实际开发bug大总结
    Android打造万能自定义阴影控件
    PagerAdapter深度解析和实践优化
    Java博客大汇总
  • 原文地址:https://www.cnblogs.com/chhokmah/p/13517111.html
Copyright © 2011-2022 走看看