标签:范围 函数 etc this arp c++ ted 时间复杂度 scanf
题意,给定 \(l,r\)
求
\[
\sum_{i=l}^{r} \varphi(i)
\]
欧拉函数筛
欧拉函数是积性函数,即 \(\varphi(a)*\varphi(b)=\varphi(ab)\)
根据定义可得
\(\varphi(p)=p-1\) (\(p\)为质数)
\(\varphi(i*p_j)=\varphi(i)*(p_j-1)\) (\(p_j\)为质数且 \(i \ge 1\) 且 \(i \%p_j >0\))
\(\varphi(i*p_j)=\varphi(i)*p_j\) \((p_j\)为质数且 \(i \ge 1\) 且 \(i \%p_j =0\))
于是预处理线性筛出范围内的每个数的欧拉函数,做一遍前缀和然后 \(O(1)\) 查询即可
时间复杂度 \(O(n)\)
然后你会发现你一会RE一会MLE
其实这题空间不够,然后还要开 unsigned long long
用 \(O(n\sqrt n)\) 的筛法就可以了
// This code writed by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
#define U unsigned
using namespace std;
const int MaxN=5000050;
template <class t> inline void read(t &s)
{
s=0;
reg int f=1;
reg char c=getchar();
while(!isdigit(c))
{
if(c=='-')
f=-1;
c=getchar();
}
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
s*=f;
return;
}
U int phi[MaxN];
// ,p[MaxN];
// int pn;
// bool vis[MaxN];
/*
inline void Init_phi()
{
phi[1]=1;
for(int i=2;i<MaxN;++i)
{
if(!vis[i])
p[++pn]=i,phi[i]=i-1;
for(int j=1;j<=pn;++j)
{
if(i*p[j]>=MaxN)
break;
vis[i*p[j]]=true;
if(!(i%p[j]))
{
phi[i*p[j]]=phi[i]*p[j];
break;
}
else
{
phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
}
return;
}
*/
inline void Init_phi()
{
phi[1]=1;
for(int i=2;i<MaxN;++i)
phi[i]=i;
for(int i=2;i<MaxN;++i)
if(phi[i]==(U)i)
for(int j=i;j<MaxN;j+=i)
phi[j]=phi[j]/i*(i-1);
return;
}
signed main(void)
{
Init_phi();
for(int i=1;i<MaxN;++i)
phi[i]=phi[i-1]+phi[i]*phi[i];
int T;cin>>T;
reg int a,b;
for(int i=1;i<=T;++i)
{
scanf("%lld %lld",&a,&b);
printf("Case %lld: %llu\n",i,phi[b]-phi[a-1]);
}
return 0;
}
LightOJ 1007 Mathematically Hard
标签:范围 函数 etc this arp c++ ted 时间复杂度 scanf
原文地址:https://www.cnblogs.com/chinesepikaync/p/12300571.html