zoukankan      html  css  js  c++  java
  • 2020CCPC长春 K

    题意:初始有 (n) 个节点 (1)(n),权值分别为 (a_1...a_n)
    有三种操作,(1.)新建标号为 (x) 的节点,权值为 (y)(2.) 合并标号为 (x)(y) 所在的树(集合)。(3.) 将标号为 (x) 的节点权值修改成 (y)。每次操作后询问 (gcd(a_i, a_j) = a_i oplus a_j) 的对数,并且要求 (i,j) 在同一树中。

    对于 (a_i) 来说,不同的 (gcd) 取值等于约数个数,考虑枚举 (a_i) 的约数并判断这个约数有没有贡献。具体的,
    对于 (a_i) 的约数 (x),我们想找到一个值 (y) 使得 (gcd(a_i,x) = x = a_i oplus y),即 (y=a_i oplus x),之后判断 (gcd(a_i,y))(x) 是否相等,进而得到 (a_i) 的一组解。

    然后 (mathcal{O}(nlog^2 n)) 的预处理贡献和 (mathcal{O}(nlog n)) 的启发式合并就可以ac了,合并的时候大概有一个几十的常数。

    #include <bits/stdc++.h>
    using namespace std;
                  
    #define fi first
    #define se second 
    #define mp make_pair
    #define pb push_back
    #define debug(x) cerr << #x << " is " << x << '
    ';
     
    typedef long long LL;
    typedef pair<int, int> pii;
    typedef unsigned long long ull;
               
    const int N = 5e5 + 5, M = 2e5, P = 1e9 + 7, INF = 0X3F3F3F3F;
    const ull D = 743, mo1 = 966335533, mo2 = 966331133;
    
    int n, q, u, v, a[N];
    int fa[N], sz[N];
    LL ans;
    std::vector<int> g[N];
    unordered_map<int, LL> dsu[N];
    
    int find(int x) {
      return x == fa[x] ? fa[x] : fa[x] = find(fa[x]);
    }
    
    int main() {
      ios::sync_with_stdio(false);
      cin.tie(nullptr);
      for (int i = 1, y; i <= M; i++) {
        for (int j = i + i; j <= M; j += i) {
          y = (j ^ i);
          if (i == __gcd(j, y)) {
            g[j].pb(y);
          }
        }
      }
      cin >> n >> q;
      for (int i = 1; i <= n; i++) {
        cin >> a[i];
        dsu[i][a[i]]++;
      }
      for (int i = 1; i <= n + q; i++) {
        fa[i] = i;
        sz[i] = 1;
      }
      for (int i = 1, op, x, y; i <= q; i++) {
        cin >> op >> x >> y;
        if (op == 1) {
          a[x] = y;
          dsu[x][y]++;
          cout << ans << '
    ';
        } else if (op == 2) {
          u = find(x), v = find(y);
          if (u != v) {
            if (sz[u] > sz[v]) swap(u, v);
            for (auto &it : dsu[u]) {
              for (auto &it1 : g[it.fi]) {
                if (dsu[v].count(it1)) ans += it.se * dsu[v][it1];
              }
            }
            for (auto &it : dsu[u]) dsu[v][it.fi] += it.se;
            dsu[u].clear();
            fa[u] = v, sz[v] += sz[u];
          }
          cout << ans << '
    ';
        } else {
          u = find(x);
          for (auto &it :g[a[x]]) {
            if (dsu[u].count(it)) ans -= dsu[u][it];
          }
          dsu[u][a[x]]--;
          a[x] = y;
          for (auto &it :g[a[x]]) {
            if (dsu[u].count(it)) ans += dsu[u][it];
          }
          dsu[u][a[x]]++;
          cout << ans << '
    ';
        }
      }
      return 0;  
    }
    
    
  • 相关阅读:
    [AX]AX2012开发新特性outer join中使用QueryFilter
    [AX]AX2012开发新特性表继承
    docker环境安装
    poj 3469
    poj 1187
    poj 1159
    poj 2135
    poj 1273
    poj 1458
    poj 1141
  • 原文地址:https://www.cnblogs.com/ChaseNo1/p/13950707.html
Copyright © 2011-2022 走看看