zoukankan      html  css  js  c++  java
  • [BZOJ2818]Gcd

    题面戳我
    题意:求

    [sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j)mbox{为质数} ] ]

    sol

    反演都会就不讲了。
    化成的式子:

    [sum_{pmbox{为质数}}^{n}sum_{d=1}^{n/p}mu(d)lfloor frac {n/p}i floor^2 ]

    其实就是

    [sum_{p=1}^{n}[pmbox{为质数}]sum_{d=1}^{n/p}mu(d)lfloor frac {n/p}i floor^2 ]

    你就当做有一个函数

    [h(x)=[xmbox{为质数}] ]

    然后对这个函数做一个前缀和就行了。还是两遍数论分块。
    复杂度(O(n))

    code

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const int N = 1e7 + 5;
    int n,mu[N],pri[N],tot,zhi[N];
    void Mobius()
    {
    	zhi[1]=mu[1]=1;
    	for (int i=2;i<=n;i++)
    	{
    		if (!zhi[i]) pri[++tot]=i,mu[i]=-1;
    		for (int j=1;j<=tot&&i*pri[j]<=n;j++)
    		{
    			zhi[i*pri[j]]=1;
    			if (i%pri[j]) mu[i*pri[j]]=-mu[i];
    			else {mu[i*pri[j]]=0;break;}
    		}
    	}
    	for (int i=1;i<=n;i++)
    		mu[i]+=mu[i-1],zhi[i]=(!zhi[i])+zhi[i-1];
    }
    ll calc(int a)
    {
    	int i=1;
    	ll res=0;
    	while (i<=a)
    	{
    		int j=a/(a/i);
    		res+=1ll*(mu[j]-mu[i-1])*(a/i)*(a/i);
    		i=j+1;
    	}
    	return res;
    }
    int main()
    {
    	scanf("%d",&n);
    	Mobius();
    	int i=1;
    	ll ans=0;
    	while (i<=n)
    	{
    		int j=n/(n/i);
    		ans+=1ll*(zhi[j]-zhi[i-1])*calc(n/i);
    		i=j+1;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    并发编程 进程
    计算机的发展史和操作系统简介
    subprocess和struct模块
    socket编程
    面向对象进阶 反射
    类的内置方法
    常用模块(hashlib,configparser,logging)

    面向对象封装 classmethod和staticmethod方法
    面向对象 继承补充和多态
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8268197.html
Copyright © 2011-2022 走看看