• BZOJ3561 DZY Loves Math VI 【莫比乌斯反演】


    题目

    给定正整数n,m。求

    输入格式

    一行两个整数n,m。

    输出格式

    一个整数,为答案模1000000007后的值。

    输入样例

    5 4

    输出样例

    424

    提示

    数据规模:

    1<=n,m<=500000,共有3组数据。

    题解

    套路反演:

    [egin{aligned} ans &= sumlimits_{d = 1}^{n} sumlimits_{i = 1}^{lfloor frac{n}{d} floor} sumlimits_{j = 1}^{lfloor frac{m}{d} floor} (frac{id * jd}{d})^{d} qquad [gcd(i,j) == 1] \ &= sumlimits_{d = 1}^{n} d^{d} sumlimits_{i = 1}^{lfloor frac{n}{d} floor} sumlimits_{j = 1}^{lfloor frac{m}{d} floor} i^{d}j^{d} qquad [gcd(i,j) == 1] \ &= sumlimits_{d= 1}^{n} d^{d} sumlimits_{k = 1}^{lfloor frac{n}{d} floor} mu(k) k^{2d} sumlimits_{i = 1}^{lfloor frac{n}{kd} floor} i^{d} sumlimits_{j = 1}^{lfloor frac{m}{kd} floor} j^{d} end{aligned} ]

    然后就慌了,好像搞不下去了
    仔细分析一下复杂度,对于每个(d),里面那堆玩意只需要(O(lfloor frac{m}{d} floor))就可以计算出来
    所以复杂度为(n)乘一个调和级数
    (O(nlogn))

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
    using namespace std;
    const int maxn = 500005,maxm = 100005,INF = 1000000000,P = 1e9 + 7;
    int p[maxn],isn[maxn],pi,mu[maxn],n,m;
    LL a[maxn],sum[maxn];
    LL qpow(LL a,LL b){
    	LL ans = 1;
    	for (; b; b >>= 1, a = a * a % P)
    		if (b & 1) ans = ans * a % P;
    	return ans;
    }
    void init(){
    	mu[1] = 1;
    	for (int i = 2; i <= n; i++){
    		if (!isn[i]) p[++pi] = i,mu[i] = -1;
    		for (int j = 1; j <= pi && i * p[j] <= n; j++){
    			isn[i * p[j]] = true;
    			if (i % p[j] == 0){
    				mu[i * p[j]] = 0;
    				break;
    			}
    			mu[i * p[j]] = -mu[i];
    		}
    	}
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	if (n > m) swap(n,m);
    	init();
    	REP(i,m) a[i] = 1;
    	LL ans = 0;
    	for (int d = 1; d <= n; d++){
    		for (LL i = 1; i <= m / d; i++){
    			a[i] = a[i] * i % P;
    			sum[i] = (sum[i - 1] + a[i]) % P;
    		}
    		LL tmp = 0;
    		for (int k = 1; k <= n / d; k++){
    			tmp = (tmp + (mu[k] * qpow(k,2 * d) % P + P) % P * sum[n / (k * d)] % P * sum[m / (k * d)] % P);
    			tmp = (tmp + P) % P;
    		}
    		ans = (ans + qpow(d,d) * tmp % P) % P;
    	}
    	ans = (ans % P + P) % P;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    window.location.href的使用方法
    hdu 2850 Load Balancing (优先队列 + 贪心)
    几种常见模式识别算法整理和总结
    【DateStructure】 Charnming usages of Map collection in Java
    编写你自己的单点登录(SSO)服务
    微软历史最高市值是多少?
    Tomcat配置一个ip绑定多个域名
    递归算法:求序列的全排列
    SMTP协议分析
    platform_device与platform_driver
  • 原文地址:https://www.cnblogs.com/Mychael/p/8976442.html
Copyright © 2020-2023  润新知