zoukankan      html  css  js  c++  java
  • 【BZOJ4407】于神之怒加强版 莫比乌斯反演

    【BZOJ4407】于神之怒加强版

    Description

    给下N,M,K.求

    Input

    输入有多组数据,输入数据的第一行两个正整数T,K,代表有T组数据,K的意义如上所示,下面第二行到第T+1行,每行为两个正整数N,M,其意义如上式所示。

    Output

    如题

    Sample Input

    1 2
    3 3

    Sample Output

    20

    HINT

    1<=N,M,K<=5000000,1<=T<=2000

    题解:如何快速推出线性筛的递推式呢?——打表。

    发现f(D)长得跟$varphi(D)$差不多?所以递推式也差不多

    $f(i*pj)=egin{cases}& f(i)*(pj^k-1) & i\%pj!=0 \ & f(i)*pj^k & i\%pj==0end{cases}$

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const ll mod=1000000007;
    const int N=5000000;
    int T,k,num;
    int pri[N];
    ll f[N+10],sf[N+10],pk[N],ans;
    bool np[N+10];
    ll pm(ll x,ll y)
    {
    	ll z=1;
    	while(y)
    	{
    		if(y&1)	z=z*x%mod;
    		x=x*x%mod,y>>=1;
    	}
    	return z;
    }
    void init()
    {
    	int i,j;
    	f[1]=sf[1]=1;
    	for(i=2;i<=N;i++)
    	{
    		if(!np[i])	pri[++num]=i,pk[num]=pm(i,k),f[i]=pk[num]-1;
    		sf[i]=sf[i-1]+f[i];
    		for(j=1;j<=num&&i*pri[j]<=N;j++)
    		{
    			np[i*pri[j]]=1;
    			if(i%pri[j]==0)
    			{
    				f[i*pri[j]]=f[i]*pk[j]%mod;
    				break;
    			}
    			f[i*pri[j]]=f[i]*(pk[j]-1)%mod;
    		}
    	}
    }
    void work()
    {
    	int n,m,i,last;
    	ans=0;
    	scanf("%d%d",&n,&m);
    	if(n>m)	swap(n,m);
    	for(i=1;i<=n;i=last+1)
    	{
    		last=min(n/(n/i),m/(m/i));
    		ans=(ans+(sf[last]-sf[i-1])*(n/i)%mod*(m/i)%mod)%mod;
    	}
    	printf("%lld
    ",(ans+mod)%mod);
    }
    int main()
    {
    	scanf("%d%d",&T,&k);
    	init();
    	while(T--)	work();
    	return 0;
    }
  • 相关阅读:
    D语言中的Range与C#中IEnumreable的区别
    D语言中使用Curl读取网页
    在D语言中如何调用Windows中的COM控件
    D语言反射
    D语言基本类型判断 traits.d
    Struts2 XML验证器
    (十四)Struts2 验证框架
    (十三)Struts2 发送电子邮件
    (十二)Struts2 数据库访问
    (十一)Struts2 文件上传
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7278460.html
Copyright © 2011-2022 走看看