zoukankan      html  css  js  c++  java
  • 莫比乌斯反演--「HAOI 2011」Problem b

    简介: 对于一些函数(f(n)),如果很难直接求出他的值,而容易其倍数或约数和(g(n)),可以通过莫比乌斯反演简化问题

    前置知识:

    • 数论分块

    其实在之前的博客里,做余数求和的时候总结过,但是也忘得差不多啦

    数论分块的过程:考虑求含有(leftlfloor frac{n}{i} ight floor)的求和式子

    对于任意一个(i)((ileq n)),我们需要找到一个最大的(j)((ileq j leq n)),满足(leftlfloor dfrac{n}{i} ight floor = leftlfloor dfrac{n}{j} ight floor),此时(j=leftlfloor frac{n}{leftlfloor frac{n}{i} ight floor} ight floor)

    这样我们可以把一些值相同的数分成一大块一起计算,是不是方便很多?

    证明:

    (k = leftlfloor frac{n}{i} ight floor),考虑证明当(leftlfloor frac{n}{j} ight floor = k)时,(j)的最大值为(leftlfloor frac{n}{k} ight floor)

    (leftlfloor frac{n}{j} ight floor = k Longleftrightarrow k leq frac{n}{j}<k+1 Longleftrightarrow frac{1}{k+1} < frac{j}{n}leq frac{1}{k} Longleftrightarrow frac{n}{k+1} < j leq frac{n}{k+1})

    又因为(j)是整数,所以(j_{max} = leftlfloor frac{n}{k} ight floor),这样我们每次以([i,j])分块求和即可

    • 莫比乌斯函数

    (mu)为莫比乌斯函数,定义为:(mu (n) = egin{cases}1&n=1\0&n含有平方因子\{(-1)}^k&k为n的本质不同的质因子个数end{cases})

    性质:

    1. (sumlimits_{dmid n} mu (d) = egin{cases} 1&n = 1\0&n eq 1end{cases})

    2. ([gcd(i,j)==1] Longleftrightarrow sumlimits_{dmid gcd(i,j)} mu (d))

    code:

    void init(){
    	mo[1] = 1;
    	for (int i = 2;i <= 1e6;i++){
    		if (!death[i]) primelist[++tot] = i,mo[i] = -1;
    		for (int j = 1;j <= tot&&i*primelist[j] <= 1e6;j++){
    			death[i*primelist[j]] = 1;
    			if (i%primelist[j] == 0){
    				mo[i*primelist[j]] = 0;
    				break;
    			}
    			mo[i*primelist[j]] = -mo[i];
    		}
    	}
    	for (int i = 1;i <= 1e6;i++) mo[i] += mo[i-1];
    }
    
    • 莫比乌斯反演

    公式:

    定义(f(n))(g(n))为两个数论函数

    如果有(f(n) = sumlimits_{dmid n}g(d)),那么有(g(n) = sumlimits_{dmid n} mu (d)f(frac{n}{d}))
    如果有(f(n) = sumlimits_{dmid n}g(d)),那么有(g(n) = sumlimits_{dmid n} mu (frac{n}{d})f(d))

    例题:

    problem:

    求符合(gcd(x,y) = k)((x,y))的个数

    solution:

    (sumlimits_{i=1}^nsumlimits_{j=1}^m [gcd(i,j) = k] Longleftrightarrow sumlimits_{i=1}^{leftlfloorfrac{n}{k} ight floor}sumlimits_{j=1}^{leftlfloorfrac{m}{k} ight floor}[gcd(i,j) = 1] Longleftrightarrow sumlimits_{i=1}^{leftlfloorfrac{n}{k} ight floor}sumlimits_{j=1}^{leftlfloorfrac{m}{k} ight floor} sumlimits_{dmid gcd(i,j)} mu (d))

    交换求和顺序,枚举(dmid gcd(i,j))即可

    (sumlimits_{d=1} mu (d)sumlimits_{i=1}^{leftlfloorfrac{n}{k} ight floor} [dmid i]sumlimits_{j=1}^{leftlfloorfrac{m}{k} ight floor} [dmid j]Longleftrightarrow sumlimits_{d=1} mu (d)leftlfloor frac{n}{k} ight floorleftlfloorfrac{m}{k} ight floor)

    code:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int read(){
    	int x = 1,a = 0;char ch = getchar();
    	while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
    	while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
    	return x*a;
    }
    const int maxn = 5e4+10;
    int n;
    int a,b,c,d,k;
    int death[maxn],primelist[maxn],tot,mu[maxn];
    void init(){
    	mu[1] = 1;
    	for (int i = 2;i <= 50000;i++){
    		if (!death[i]) primelist[++tot] = i,mu[i] = -1;
    		for (int j = 1;j <= tot&&i*primelist[j] <= 50000;j++){
    			death[i*primelist[j]] = 1;
    			if (i%primelist[j] == 0){
    				mu[i*primelist[j]] = 0;
    				break;
    			}
    			mu[i*primelist[j]] = -mu[i];
    		}
    	}
    	for (int i = 1;i <= 50000;i++) mu[i] += mu[i-1];
    }
    int solve(int n,int m){
    	int res = 0;
    	for (int l = 1,r;l <= min(n,m);l = r+1){
    		r = min(n/(n/l),m/(m/l));
    		res += (mu[r]-mu[l-1])*(n/l)*(m/l);
    	}
    	return res;
    }
    int main(){
    	n = read();init();
    	for (int i = 1;i <= n;i++){
    		a = read(),b = read(),c = read(),d = read(),k = read();
    		 printf("%d
    ", solve(b/k,d/k)-solve(b/k,(c-1)/k)-solve((a-1)/k,d/k)+solve((a-1)/k,(c-1)/k));
    	}
    	return 0;
    }
    
  • 相关阅读:
    MybatisPlus自动填充公共字段的策略
    docker内的应用访问宿主机上的mysql和Redis
    Spingboot整合Redis,用注解(@Cacheable、@CacheEvict、@CachePut、@Caching)管理缓存
    集群中的session共享问题解决方案
    Java并发之原子性,有序性,可见性,以及Happen-Before原则
    Java NIO技术概述
    Java反射机制总结
    java线程以及定时任务
    java流概述以及文件读写示例
    CSS常用内容总结(二)
  • 原文地址:https://www.cnblogs.com/little-uu/p/14033232.html
Copyright © 2011-2022 走看看