https://nanti.jisuanke.com/t/30999
题意
f(i)表示i能拆分成两个数的乘积,且要求这两个数中各自都没有出现超过1次的质因子的方案数。每次给出n,求∑(n,i=1)f(i)
分析
n到2e7,肯定得打表离线做。
类似打欧拉函数表的方式,对于数d以及素数p,f(p)=2;
当d|p时,若d|p^2,则f(d∗p)=0;否则f(d∗p)=f(d)/2;
当d†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(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(maxn); int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); printf("%lld ",res[n]); } return 0; }