zoukankan      html  css  js  c++  java
  • BZOJ3529 [Sdoi2014]数表【莫比乌斯反演】

    Description

    有一张 n×m 的数表,其第 i 行第 j 列(1 <= i <= n, 1 <= j <= m)的数值为
    能同时整除 i 和 j 的所有自然数之和。给定 a , 计算数表中不大于 a 的数之和。

    Input

    输入包含多组数据。
    输入的第一行一个整数Q表示测试点内的数据组数
    接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。
    1 < =N.m < =10^5 , 1 < =Q < =2×10^4

    Output

    对每组数据,输出一行一个整数,表示答案模2^31的值。

    Sample Input

    2
    4 4 3
    10 10 5

    Sample Output

    20
    148


    题解%%%%贝神的blog,我就不赘述了


    //Author: dream_maker
    #include<bits/stdc++.h>
    using namespace std;
    //----------------------------------------------
    //typename
    typedef long long ll;
    //convenient for
    #define fu(a, b, c) for (int a = b; a <= c; ++a)
    #define fd(a, b, c) for (int a = b; a >= c; --a)
    #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
    //inf of different typename
    const int INF_of_int = 1e9;
    const ll INF_of_ll = 1e18;
    //fast read and write
    template <typename T>
    void Read(T &x) {
      bool w = 1;x = 0;
      char c = getchar();
      while (!isdigit(c) && c != '-') c = getchar();
      if (c == '-') w = 0, c = getchar();
      while (isdigit(c)) {
        x = (x<<1) + (x<<3) + c -'0';
        c = getchar();
      }
      if (!w) x = -x;
    }
    template <typename T>
    void Write(T x) {
      if (x < 0) {
        putchar('-');
        x = -x; 
      }
      if (x > 9) Write(x / 10);
      putchar(x % 10 + '0');
    }
    //----------------------------------------------
    const int N = 1e5 + 10;
    int prime[N], mu[N], tot = 0;
    bool vis[N];
    int sum[N], pre[N], ans[N];
    struct Ques {
      int n, m, id, a;
    } Q[N];
    bool operator < (const Ques a, const Ques b) {
      return a.a < b.a;
    }
    struct Node {
      int id, vl;
    } P[N];
    bool operator < (const Node a, const Node b) {
      return a.vl < b.vl;
    }
    void init() {
      mu[1] = sum[1] = pre[1] = 1;
      P[1] = (Node){1, 1};
      fu(i, 2, N - 1) {
        if (!vis[i]) {
          prime[++tot] = i;
          mu[i] = -1;
          sum[i] = pre[i] = i + 1;
        }
        fu(j, 1, tot) {
          int nxt = i * prime[j];
          if (nxt >= N) break;
          vis[nxt] = 1;
          if (i % prime[j]) {
            pre[nxt] = prime[j] + 1;
            sum[nxt] = sum[i] * sum[prime[j]];
            mu[nxt] = -mu[i];
          } else {
            pre[nxt] = pre[i] * prime[j] + 1;
            sum[nxt] = sum[i] / pre[i] * pre[nxt];
            mu[nxt] = 0;
            break; 
          }
        }
        P[i] = (Node){i, sum[i]};
      }
    }
    int bit[N];
    void add(int x, int vl) {
      for (; x < N; x += x & (-x)) bit[x] += vl;
    }
    int query(int x) {
      int res = 0;
      for (; x; x -= x & (-x)) res += bit[x];
      return res; 
    } 
    int main() {
      init();
      int T; Read(T);
      fu(i, 1, T) {
        Read(Q[i].n), Read(Q[i].m), Read(Q[i].a);
        Q[i].id = i; 
      }
      sort(Q + 1, Q + T + 1);
      sort(P + 1, P + N);
      int now = 1;
      fu(i, 1, T) {
        while (now < N && P[now].vl <= Q[i].a) {
          fu(j, 1, (N - 1) / P[now].id) {
            add(j * P[now].id, mu[j] * P[now].vl);
          }
          ++now;
        }
        int limit = min(Q[i].n, Q[i].m), k = 0;
        for (int j = 1; j <= limit; j = k + 1) {
          k = min(Q[i].n / (Q[i].n / j), Q[i].m / (Q[i].m / j));
          ans[Q[i].id] += (Q[i].n / j) * (Q[i].m / j) * (query(k) - query(j - 1));
        }
      }
      fu(i, 1, T) {
        Write(ans[i] & 2147483647);
        putchar('
    ');
      }
      return 0;
    }
    
  • 相关阅读:
    Android ImageView设置图片原理(下)
    C++ 虚函数表 多重继承
    C++ 虚函数表 单继承
    私有继承
    内联函数和宏定义的区别
    #pragma pack(x) CPU对齐
    static 变量(静态变量)
    C++ 中const作用
    如何连接宏参数
    几种常见容器比较和分析 hashmap, map, vector, list ...hash table
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9794392.html
Copyright © 2011-2022 走看看