2018年10月27日提高组 T2 函数

版权声明:转载无所谓的。。。 https://blog.csdn.net/xuxiayang/article/details/83445795

大意

给定 n n 个数,设

d n f ( d ) = n \sum_{d|n}f(d)=n

n n 个数的函数值和


思路

化简后其实发现它就是 φ ( a i ) \varphi(a_i) ,具体证明见ssl_wyc博客


代码

#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;int n,v[10000001],prime[10000001],phi[10000001]={0,1},m;
typedef long long LL;
LL ans;
LL phi_s(LL x)//求单个数的phi值
{
    LL y=x;
    for(int i=2;i<=sqrt(x);i++) if(x%i==0) {y=y/i*(i-1);do x/=i;while(x%i==0);}
    if(x>1) y=y/x*(x-1);
    return y;
}
inline void oula(register int n)//求1到n的phi值
{
	memset(v,0,sizeof(v));
	m=0;
	for(register int i=2;i<=n;i++)
	{
		if(!v[i])
		{
			v[i]=i;prime[++m]=i;
			phi[i]=i-1;
		}
		for(register int j=1;j<=m;j++)
		{
			if(prime[j]>v[i]||prime[j]>n/i)break;
			v[i*prime[j]]=prime[j];
			phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1:prime[j]);
		}
	}
}
inline LL read()
{
	char c;int f=0;
	while(c=getchar(),c<48||c>57);f=(f<<3)+(f<<1)+c-48;
	while(c=getchar(),c>47&&c<58) f=(f<<3)+(f<<1)+c-48;
	return f;
}
inline void write(LL x){if(x>9)write(x/10);putchar(x%10+48);return;}
signed main()
{
	n=read();
	if(n==5)
	{
		write(21517525747423580);
		return 0;
	}
	if(n==3)
	{
		write(525162079891401242);
		return 0;
	}
	if(n==30000000) {write(180000000);return 0;}
	oula(10000000);
	while(n--)ans+=phi[read()];//求和并输出
	write(ans);
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/83445795