zoukankan      html  css  js  c++  java
  • 51nod 1190 最小公倍数之和 V2【莫比乌斯反演】

    参考:http://blog.csdn.net/u014610830/article/details/49493279
    这道题做起来感觉非常奇怪啊……头一次见把mu推出来再推没了的……

    [sum_{i=a}^{b}lcm(i,b) ]

    [sum_{i=a}^{b}frac{i*b}{gcd(i,b)} ]

    [sum_{d|b}sum_{i=a}^{b}[gcd(i,b)==d]frac{ib}{d} ]

    [sum_{d|b}sum_{i=left lfloor frac{a}{d} ight floor}^{left lfloor frac{b}{d} ight floor}[gcd(i,b)==1]frac{idb}{d} ]

    [bsum_{d|b}sum_{i=left lfloor frac{a}{d} ight floor}^{left lfloor frac{b}{d} ight floor}[gcd(i,b)==1]i ]

    [bsum_{d|b}sum_{i=left lfloor frac{a}{d} ight floor}^{left lfloor frac{b}{d} ight floor}isum_{k|gcd(i,frac{b}{d})}mu(k) ]

    [bsum_{d|b}sum_{k|frac{b}{d}}mu(k)sum_{i=left lfloor frac{a}{d} ight floor}^{left lfloor frac{b}{d} ight floor,k|i}i ]

    [bsum_{d|b}sum_{k|frac{b}{d}}mu(k)ksum_{i=left lfloor frac{a}{dk} ight floor}^{left lfloor frac{b}{dk} ight floor}i ]

    [f(a,b)=sum_{i=a}^{b}i ]

    [bsum_{d|b}sum_{k|frac{b}{d}}mu(k)kf(left lfloor frac{a}{dk} ight floor,left lfloor frac{b}{dk} ight floor) ]

    枚举dk

    [bsum_{d|b}f(frac{a}{d},frac{b}{d})sum_{k|d}mu(k)k ]

    其中f可以( O(1) )算,设( g(x)=sum_{k|x}mu(k)k ),容易发现这是积性的,显然设p为质数,( g(p)=1-p,g(p^k)=1-p ),于是这样就把mu推掉了
    时间复杂度很不科学但是还是能过

    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int N=100005,m=100000,inv2=500000004,mod=1e9+7;
    int T,n,q[N],tot,a,b,p[N],cnt,len[N];
    bool v[N];
    vector<int>fac;
    void dfs(int re,int l)
    {
    	if(l>cnt)
    	{
    		fac.push_back(re);
    		return;
    	}
    	int tmp=1;
    	dfs(re,l+1);
    	for(int i=1;i<=len[l];i++)
    	{
    		tmp*=p[l];
    		dfs(re*tmp,l+1);
    	}
    }
    int main()
    {
    	v[1]=1;
    	for(int i=2;i<=m;i++)
    	{
    		if(!v[i])
    			q[++tot]=i;
    		for(int j=1;j<=tot&&i*q[j]<=m;j++)
    		{
    			int k=i*q[j];
    			v[k]=1;
    			if(i%q[j]==0)
    				break;
    		}
    	}
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d",&a,&b);
    		cnt=0;
    		int now=b;
    		for(int i=1;i<=tot&&q[i]*q[i]<=now;i++)
    		{
    			if(now%q[i]==0)
    			{
    				p[++cnt]=q[i];
    				len[cnt]=0;
    			}
    			while(now%q[i]==0)
    			{
    				now/=q[i];
    				len[cnt]++;
    			}
    		}
    		if(now>1)
    		{
    			p[++cnt]=now;
    			len[cnt]=1;
    		}
    		fac.clear();
    		dfs(1,1);//cout<<cnt<<endl;
    		long long ans=0ll;
    		for(int i=0;i<fac.size();i++)
    		{
    			int v=fac[i];
    			long long tt=a+v-1,tmp,re=1ll;
    			tmp=(((tt/v+b/v)%mod)*((b/v-tt/v+1+mod)%mod)%mod)*inv2%mod;
    			for(int j=1;j<=cnt;j++)
    				if(v%p[j]==0)
    					re=re*((1-p[j]+mod)%mod)%mod;
    			ans=((ans+re*tmp%mod)%mod+mod)%mod;
    		}
    		printf("%lld
    ",ans*b%mod);
    	}
    	return 0;
    }
    
  • 相关阅读:
    2019年11月28日开发手记
    2019年11月26日开发手记
    2019年11月25日开发手记
    2019年11月24日开发手记
    2019年11月23日开发手记
    R学习
    python学习目录
    自动化测试appium
    python爬虫的进阶用法
    asyncio
  • 原文地址:https://www.cnblogs.com/lokiii/p/8320189.html
Copyright © 2011-2022 走看看