ACM-ICPC 2018 南京赛区网络预赛 - J. Sum (找规律+打表)
Posted xiuwenli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM-ICPC 2018 南京赛区网络预赛 - J. Sum (找规律+打表)相关的知识,希望对你有一定的参考价值。
题意:(f(i):i)能拆分成两个数的乘积,且要求这两个数中各自都没有出现超过1次的质因子。每次给出n,求(sum_{i=1}^{n}f(i))
分析:(1 le n le 2e7),每次查询若都(O(n))统计,肯定超时,必须打表。
类似打欧拉函数表的方式,对于数(d)以及素数(p),(f(p)=2);
当(d|p)时,若(d|p^2),则(f(d*p^2)=0);否则(f(d*p)=f(d)/2);
当(ddagger p)时,(f(d*p) = f(d)*2)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=2e7+5;
bool vis[maxn];
int prime[maxn];
LL f[maxn];
LL res[maxn];
void init_f(int n){
int cnt=0;
f[1]=1;
for(int i=2;i<n;i++){
if(!vis[i]){
prime[cnt++]=i;
f[i]=2;
}
for(int j=0;j<cnt&&i*prime[j]<n;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0){
if(i%(prime[j]*prime[j])==0) f[i*prime[j]]= 0;
else f[i*prime[j]]= f[i]/2;
break;
}
else{
f[i*prime[j]]= f[i]*2;
}
}
}
for(int i=1;i<maxn;++i) res[i] = res[i-1]+f[i];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
init_f(maxn);
int T; scanf("%d",&T);
while(T--){
int n; scanf("%d",&n);
printf("%lld
",res[n]);
}
return 0;
}
以上是关于ACM-ICPC 2018 南京赛区网络预赛 - J. Sum (找规律+打表)的主要内容,如果未能解决你的问题,请参考以下文章
ACM-ICPC 2018 南京赛区网络预赛 Lpl and Energy-saving Lamps 线段树