zoukankan      html  css  js  c++  java
  • 「NOI2016」循环之美

    传送门

    这个题面一眼看过去没什么想法,尝试转化题意。

    假设我们现在有合法的一组 (x, y),显然我们先要有 (x perp y)

    (frac{x}{y})(k) 进制下是一个循环节长度为 (l) 的循环小数。

    那么我们显然可以得到 ([frac{xk^l}{y}] = [frac{x}{y}]),也就是两者的小数部分相等。

    那么我们可以进一步推导:

    [egin{split} [frac{xk^l}{y}] = [frac{x}{y}] & Rightarrow frac{xk^l}{y} - lfloor frac{xk^l}{y} floor = frac{x}{y} - lfloor frac{x}{y} floor \ & Rightarrow xk^l - lfloor frac{xk^l}{y} floor imes y = x - lfloor frac{x}{y} floor imes y \ & Rightarrow xk^l equiv x (mod y) \ & Rightarrow k^l equiv 1 (mod y)quadquad(gcd(x, y) = 1) \ & Rightarrow k perp y end{split} ]

    推导到这里我们就不难发现其实我们是要求一个这样的东西:

    [f(n, m, k) = sum_{i = 1} ^ n sum_{j = 1} ^ m [i perp j] [j perp k] ]

    考虑化简后面那一坨:

    [egin{split} f(n, m, k) & = sum_{i = 1} ^ n sum_{j = 1} ^ m [i perp j] [j perp k] \ & = sum_{i = 1} ^ n sum_{j = 1} ^ m [i perp j] sum_{d | j, d | k} mu(d) \ & = sum_{d = 1} ^ {min(n, m)} mu(d) sum_{d | j} sum_{i = 1} ^ n [i perp j] \ & = sum_{d = 1} ^ {min(n, m)} mu(d) sum_{j = 1} ^ {lfloor frac{m}{d} floor} sum_{i = 1} ^ n [j perp i] [i perp d] \ & = sum_{d = 1} ^ {min(n, m)} mu(d) f(lfloor frac{m}{d} floor, n, d) end{split} ]

    边界:

    (f(n, 0, k) = f(0, m, k) = 0, f(n, m, 1) = sum_{i = 1} ^ n sum_{j = 1} ^ m [i perp j] = sum_{d = 1} ^ {min(n, m)} mu(d) lfloor frac{n}{d} floor lfloor frac{m}{d} floor)

    杜教筛 (mu),然后递归求就是了。

    参考代码:

    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <map>
    using namespace std;
    
    typedef long long LL;
    const int _ = 1e7 + 5;
    
    int vis[_], num, pri[_]; LL mu[_], s[_];
    vector < int > fac;
    map < int, LL > ans;
    
    void seive() {
        mu[1] = 1;
        for (int i = 2; i < _; ++i) {
            if (!vis[i]) mu[i] = -1, pri[++num] = i;
            for (int j = 1; j <= num && i * pri[j] < _; ++j) {
                vis[i * pri[j]] = 1;
                if (i % pri[j] == 0) break ;
                mu[i * pri[j]] = -mu[i];
            }
        }
        for (int i = 1; i < _; ++i) s[i] = s[i - 1] + mu[i];
    }
    
    LL Sum(int n) {
        if (n < _) return s[n]; else if (ans[n]) return ans[n];
        LL res = 1;
        for (int l = 2, r; l <= n; l = r + 1)
            r = n / (n / l), res -= 1ll * (r - l + 1) * Sum(n / l);
        return ans[n] = res;
    }
    
    LL solve(int n, int m, int k) {
        if (!n || !m) return 0;
        LL res = 0;
        if (k == 1) {
            for (int l = 1, r; l <= min(n, m); l = r + 1)
                r = min(n / (n / l), m / (m / l)), res += 1ll * (Sum(r) - Sum(l - 1)) * (n / l) * (m / l);
            return res;
        }
        for (int i = 0; i < fac.size(); ++i)
            if (k % fac[i] == 0 && mu[fac[i]])
                res += mu[fac[i]] * solve(m / fac[i], n, fac[i]);
        return res;
    }
    
    int n, m, k;
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("cpp.in", "r", stdin), freopen("cpp.out", "w", stdout);
    #endif
        seive();
        scanf("%d %d %d", &n, &m, &k);
        for (int i = 1; i * i <= k; ++i)
            if (k % i == 0) {
                fac.push_back(i);
                if (i * i != k) fac.push_back(k / i);
            }
        printf("%lld
    ", solve(n, m, k));
        return 0;
    }
    
  • 相关阅读:
    ThreadLocal 详解
    外键的约束(Mysql、PostgreSQL)
    Linux命令中,$、#、@、0、1、2、*、?的作用
    $.ajax 方法参数总是记不住,在这里记录一下
    SVN提示https证书验证失败问题svn: E230001: Server SSL certificate verification failed:
    各类资源地址整合
    CentOS 7 上安装vim 解決 centos -bash: vim: command not found
    Beyond Compare 4提示已经过了30天试用期,破解方式,亲测可用
    Django 04 模板标签(if、for、url、with、autoeacape、模板继承于引用、静态文件加载)
    Django 03 模板路径、模板变量、常用的过滤器
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/13138142.html
Copyright © 2011-2022 走看看