zoukankan      html  css  js  c++  java
  • [BZOJ4407]于神之怒加强版

    题面戳我
    Description
    给下N,M,K.求

    [sum_{i=1}^{n}sum_{j=1}^{m}gcd(i,j)^kquad(modquad1e9+7) ]

    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

    sol

    首先单组数据(O(n))的都会噻,就不讲了。(就是内外数论分块(O(sqrt n*sqrt n)=O(n))的那种)
    这种方法化到最后的答案式应该是

    [ans=sum_{d=1}^{n}d^ksum_{i=1}^{n/d}mu(i)lfloorfrac n{di} floorlfloorfrac m{di} floor ]

    我们现在令(T=di),然后考虑分别计算每一个(lfloorfrac nT floorlfloorfrac mT floor)对答案的贡献

    [ans=sum_{T=1}^{n}lfloorfrac nT floorlfloorfrac mT floor*sum_{d|T}d^kmu(frac Td) ]

    (手玩一下发现就是这样的)
    前面那一坨显然还是(O(sqrt n))分块,后面那一坨发现是一个狄利克雷卷积的形式,就是说

    [h(T)=sum_{d|T}d^kmu(frac Td) ]

    是一个积性函数。所以线性筛出来后维护一个前缀和即可。

    code

    这份代码比yyb的慢了整整一倍。
    原因是我已经被int溢出给搞怕了所以全开long long(是全开!)
    所以说如果你想像yyb 这种港记跑得一样快的话请使用int类型并在适当的地方加上1ll*
    我不会说我因为ans没有清零WA了两次的

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const ll N = 5000005;
    const ll maxn = 5000000;
    const ll mod = 1e9 + 7;
    ll gi()
    {
    	ll x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    ll fastpow(ll a,ll b)
    {
    	ll s=1;
    	while (b)
    	{
    		if (b&1) s=s*a%mod;
    		a=a*a%mod;b>>=1;
    	}
    	return s;
    }
    ll t,k,n,m,pri[N],tot,zhi[N],low[N],h[N],ans;
    void Mobius()
    {
    	zhi[1]=h[1]=low[1]=1;
    	for (ll i=2;i<=maxn;i++)
    	{
    		if (!zhi[i]) low[i]=pri[++tot]=i,h[i]=(fastpow(i,k)-1+mod)%mod;
    		for (ll j=1;j<=tot&&i*pri[j]<=maxn;j++)
    		{
    			zhi[i*pri[j]]=1;
    			if (i%pri[j]==0)
    			{
    				low[i*pri[j]]=low[i]*pri[j];
    				if (low[i]==i)
    					h[i*pri[j]]=h[i]*(h[pri[j]]+1)%mod;
    				else
    					h[i*pri[j]]=h[i/low[i]]*h[low[i]*pri[j]]%mod;
    				break;
    			}
    			low[i*pri[j]]=pri[j];
    			h[i*pri[j]]=h[i]*h[pri[j]]%mod;
    		}
    	}
    	for (ll i=1;i<=maxn;i++) h[i]=(h[i]+h[i-1])%mod;
    }
    int main()
    {
    	t=gi();k=gi();
    	Mobius();
    	while (t--)
    	{
    		n=gi();m=gi();ans=0;
    		if (n>m) swap(n,m);
    		ll i=1;
    		while (i<=n)
    		{
    			ll j=min(n/(n/i),m/(m/i));
    			ans=(ans+(h[j]-h[i-1]+mod)%mod*((n/i)*(m/i)%mod)%mod)%mod;
    			i=j+1;
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    HTTP协议开发应用-文件服务器
    编解码-marshalling
    编解码-protobuf
    编解码-java序列化
    算法笔记_114:等额本金(Java)
    算法笔记_113:算法集训之代码填空题集一(Java)
    算法笔记_112:第五届蓝桥杯软件类省赛真题(Java本科B组)试题解答
    算法笔记_111:第五届蓝桥杯软件类省赛真题(Java本科A组)试题解答
    算法笔记_110:第四届蓝桥杯软件类省赛真题(JAVA软件开发高职高专组部分习题)试题解答
    算法笔记_109:第四届蓝桥杯软件类省赛真题(JAVA软件开发本科B组部分习题)试题解答
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8261241.html
Copyright © 2011-2022 走看看