• BZOJ3561 DZY Loves Math VI 数论 快速幂 莫比乌斯反演


    原文链接http://www.cnblogs.com/zhouzhendong/p/8116330.html

    UPD(2018-03-26):回来重新学数论啦。之前的博客版面放在更新之后的后面。


    题目传送门 - BZOJ3561


    题意概括

      给出$n,m$,求$Largesum_{i=1}^nsum_{j=1}^m lcm(i,j)^{gcd(i, j)}$。

      $1leq n,mleq 500000$

    题解

      先推式子:(假设$nleq m$)

      $$sum_{i=1}^nsum_{j=1}^m lcm(i,j)^{gcd(i, j)}\=sum_{d=1}^{n}sum_{i=1}^{leftlfloorfrac nd ight floor}sum_{j=1}^{leftlfloorfrac md ight floor}(ijd)^dcdot[gcd(i,j)=1]\=sum_{d=1}^{n}sum_{i=1}^{leftlfloorfrac nd ight floor}sum_{j=1}^{leftlfloorfrac md ight floor}(ijd)^dcdotsum_{p|i,p|j}mu(p)\=sum_{d=1}^{n}d^{d}sum_{p=1}^{leftlfloorfrac nd ight floor}mu(p)sum_{i=1}^{leftlfloorfrac{n}{pd} ight floor}sum_{j=1}^{leftlfloorfrac{m}{pd} ight floor}(ijp^2)^d\=sum_{d=1}^{n}d^{d}sum_{p=1}^{leftlfloorfrac nd ight floor}mu(p)p^{2d}sum_{i=1}^{leftlfloorfrac {n}{pd} ight floor}i^dsum_{j=1}^{leftlfloorfrac{m}{pd} ight floor}j^d$$

      然后发现对于$d^d$可以直接快速幂。对于某一个$d$,要枚举的$p$有$O(frac nd)$个,对于后面的一堆数的幂和,只要前缀和预处理,要处理的个数也是$O(frac md)$的。所以总复杂度为$O(n log n)$。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=500005;
    const LL mod=1e9+7;
    int n,m,prime[N],u[N],pcnt=0;
    bool f[N];
    void init(int n){
    	memset(f,true,sizeof f);
    	f[0]=f[1]=0,u[1]=1;
    	for (int i=2;i<=n;i++){
    		if (f[i])
    			prime[++pcnt]=i,u[i]=-1;
    		for (int j=1;j<=pcnt&&i*prime[j]<=n;j++){
    			f[i*prime[j]]=0;
    			if (i%prime[j])
    				u[i*prime[j]]=-u[i];
    			else {
    				u[i*prime[j]]=0;
    				break;
    			}
    		}
    	}
    }
    LL Pow(LL x,LL y){
    	if (!y)
    		return 1LL;
    	LL xx=Pow(x,y/2);
    	xx=xx*xx%mod;
    	if (y&1LL)
    		xx=xx*x%mod;
    	return xx;
    }
    LL pows[N],sum[N];
    int main(){
    	scanf("%d%d",&n,&m);
    	if (n>m)
    		swap(n,m);
    	init(n);
    	for (int i=1;i<=m;i++)
    		pows[i]=1;
    	LL ans=0;
    	for (int d=1;d<=n;d++){
    		LL now=0;
    		sum[0]=0;
    		for (int i=1;i<=m/d;i++)
    			pows[i]=pows[i]*i%mod,sum[i]=(sum[i-1]+pows[i])%mod;
    		for (int p=1;p<=n/d;p++)
    			now=(now+u[p]*pows[p]*pows[p]%mod*sum[n/p/d]%mod*sum[m/p/d])%mod;
    		now=(now%mod+mod)%mod;
    		ans=(ans+Pow(d,d)*now)%mod;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

      

    ——————old——————

    题意概括

    给定正整数n,m。求
     

    题解

    博主越来越懒了。

    http://blog.csdn.net/lych_cys/article/details/50721642?locationNum=1&fps=1


    代码

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int N=500005;
    const LL mod=1e9+7;
    LL n,m,u[N],prime[N],pcnt,v[N],sum[N];
    bool isprime[N];
    LL Pow(LL x,LL y){
    	if (y==0)
    		return 1LL;
    	LL xx=Pow(x,y/2);
    	xx=xx*xx%mod;
    	if (y&1LL)
    		xx=xx*x%mod;
    	return xx;
    }
    void Get_Mobius(){
    	memset(isprime,true,sizeof isprime);
    	isprime[0]=isprime[1]=pcnt=0;
    	u[1]=1;
    	for (LL i=2;i<=n;i++){
    		if (isprime[i])
    			u[i]=-1,prime[++pcnt]=i;
    		for (LL j=1;j<=pcnt&&i*prime[j]<=n;j++){
    			isprime[i*prime[j]]=0;
    			if (i%prime[j])
    				u[i*prime[j]]=-u[i];
    			else {
    				u[i*prime[j]]=0;
    				break;
    			}
    		}
    	}
    }
    int main(){
    	scanf("%lld%lld",&n,&m);
    	if (n<m)
    		swap(n,m);
    	Get_Mobius();
    	for (int i=1;i<=n;i++)
    		v[i]=1;
    	LL ans=0;
    	for (LL d=1;d<=m;d++){
    		sum[0]=0;
    		for (LL i=1;i<=(LL)(n/d);i++)
    			v[i]=v[i]*i%mod,sum[i]=(v[i]+sum[i-1])%mod;
    		LL res=0;
    		for (LL p=1;p<=(LL)(m/d);p++)
    			res=(res+v[p]*v[p]%mod*u[p]*sum[n/d/p]%mod*sum[m/d/p]%mod+mod)%mod;
    		ans=(ans+res*Pow(d,d))%mod;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    android 发送短信 怎样做到一条一条的发送,仅仅有在上一条发送成功之后才发送下一条短信
    qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果
    C小加 之 随机数
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    WIZnet推出串口转以太网模块WIZ550S2E
    java里,当long与上了int
    几个常见字符串处理函数的实现原理
    Android平台调用Web Service:演示样例
    怎样学好游戏编程
    void及void指针含义的深刻解析
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ3561.html
Copyright © 2020-2023  润新知