• [SDOI2015] 约数个数和



    Portal

    考虑这样一个式子:

    [d(ij) = sum_{x | i}sum_{y | j} [x ot y] ]

    怎么证明? 一开始我们一定会想到$$d(ij) = sum_{x | i} sum_{y | j} 1 $$ 但这样会计算重复. 于是我们考虑:

    [d(ij) = sum_{x | i}sum_{frac{j}{y} | j}1 ]

    这样每个因数就变成$ frac{xj}{y} $, 如果x和y不互质. 那么就会有 $ frac{(xj)p}{yp} == frac{xj}{y} $

    如果xp,yp同时是i, j的因数那就会算重复.

    所以一定要求此二者互质.

    相应的:

    [sigma(ij) = sum_{x | i}sum_{y | j} [x ot y]x frac{}{} frac{j}{y} ]


    那么我们可以开始化式子了!!

    [Ans = sum_{i}sum_{j} sum_{x | i}sum_{y | j}[(x, y) == 1] \ = sum_{x} sum_{y}[(x, y) == 1]sum_{i} sum_{j} [x | i][y | j] \ = sum_{x} sum_{y}sum_{d | (x, y)} mu(d) lfloorfrac{n}{x} floorlfloorfrac{m}{y} floor\ = sum_{d} mu(d) sum_{x}sum_{y}[d | x][d | y] lfloorfrac{n}{x} floorlfloorfrac{m}{y} floor \ = sum_{d} mu(d) sum_{x}^{n / d}lfloorfrac{n}{xd} floorsum_{y}^{m / d}lfloorfrac{m}{yd} floor\ ]

    (F(n) = sum_{i = 1}^{n} sigma_0(i))

    那么有

    [Ans = sum_{d} mu(d) F(frac{n}{d})F(frac{m}{d}) ]

    然后线性筛/杜教筛Min25筛洲阁筛筛以下约数个数的前缀和就可以做了.

    Codes

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
    #define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
    #define clar(a, b) memset((a), (b), sizeof(a))
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    typedef long long LL;
    typedef long double LD;
    int read() {
        char ch = getchar();
        int x = 0, flag = 1;
        for (;!isdigit(ch); ch = getchar()) if (ch == '-') flag *= -1;
        for (;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
        return x * flag;
    }
    void write(int x) {
        if (x < 0) putchar('-'), x = -x;
        if (x >= 10) write(x / 10);
        putchar(x % 10 + 48);
    }
    
    const int Maxn = 50009;
    int prime[Maxn], isnprime[Maxn], mu[Maxn], prefixMu[Maxn], tot, low[Maxn];
    LL sigma0[Maxn];
    void linearSieve() {
    	mu[1] = 1; sigma0[1] = 1;
    	rep (i, 2, Maxn - 1) {
    		if (!isnprime[i]) mu[i] = -1, prime[++tot] = i, low[i] = i, sigma0[i] = 2;
    		for (int k, j = 1; j <= tot && (k = prime[j] * i) < Maxn; ++j) {
    			isnprime[k] = 1;
    			if (i % prime[j] == 0) {
    				mu[k] = 0; low[k] = low[i] * prime[j];
    				sigma0[k] = (low[i] == i) ? (sigma0[i] + 1) : (sigma0[k / low[k]] * sigma0[low[k]]);
    				break;
    			} else {
    				mu[k] = -mu[i]; low[k] = prime[j];
    				sigma0[k] = sigma0[i] * sigma0[prime[j]];
    			}
    		}
    	}
    	rep (i, 1, Maxn - 1) {
    		prefixMu[i] = prefixMu[i - 1] + mu[i];
    		sigma0[i] += sigma0[i - 1];
    	}
    }
    
    void init() { linearSieve(); }
    
    void solve() {
    	int T = read();
    	while (T--) {
    		int n = read(), m = read();
    		LL ans = 0; int Limit = min(n, m);
    		for (int l = 1, r; l <= Limit; l = r + 1) {
    			r = min(Limit, min(n / (n / l), m / (m / l)));
    			ans += (prefixMu[r] - prefixMu[l - 1] * 1ll) * sigma0[n / l] * sigma0[m / l];
    		}
    		printf("%lld
    ", ans);
    	}
    }
    
    int main() {
    	freopen("BZOJ3994.in", "r", stdin);
    	freopen("BZOJ3994.out", "w", stdout);
    
    	init();
    	solve();
    
    #ifdef Qrsikno
        debug("
    Running time: %.3lf(s)
    ", clock() * 1.0 / CLOCKS_PER_SEC);
    #endif
        return 0;
    }
    
    
  • 相关阅读:
    洛谷 P1879 [USACO06NOV]玉米田Corn Fields
    洛谷 P2709 小B的询问
    洛谷 P1972 [SDOI2009]HH的项链
    洛谷 P3648 [APIO2014]序列分割
    洛谷 P2157 [SDOI2009]学校食堂
    洛谷 P1198 [JSOI2008]最大数
    洛谷 P3870 [TJOI2009]开关
    【模板】线段树2
    【模板】线段树1
    git之远程标签下载(远程分支)
  • 原文地址:https://www.cnblogs.com/qrsikno/p/10197823.html
Copyright © 2020-2023  润新知