https://www.jisuanke.com/contest/1555?view=challenges
题意:
题解:写完都没发现是个积性函数233
想法就是对x分解质因数,f(x)就是2^k,其中k是x分解结果中次数为一的质因子个数。如果有某个次数大于等于3,f(x)==0;
这样明显会TLE
所以就想一个递推的方法。
于是魔改了一下线性筛。
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<iomanip> #include<queue> #include<map> #include<bitset> #include<stack> #include<vector> #include<set> using namespace std; #define MAXN 1010 #define MAXM 1010 #define INF 1000000000 #define MOD 1000000007 #define ll long long #define eps 5e-6 ll n, N; #define rep(i,t,n) for(int i =(t);i<=(n);++i) #define per(i,n,t) for(int i =(n);i>=(t);--i) #define mmm(a,b) memset(a,b,sizeof(a)) const int maxn=2e7+1e5; int num = 0; int vis[maxn], pri[maxn]; ll f[maxn]; ll s[maxn]; void init() { rep(i, 1, maxn)f[i] = 1; mmm(vis, 0); mmm(pri, 0); num = 0; } void getpri() { for ( ll i = 2; i<N; i++) { if (!vis[i])pri[++num] = i,f[i]=2; for ( ll j = 1; j <= num && pri[j] * i<N; j++) { vis[pri[j] * i] = 1; f[pri[j] * i] *= f[pri[j]]*f[i]; if (i%pri[j] == 0) { //二次方 f[pri[j] * i] /= 4; if (i%(pri[j] * pri[j]) == 0)f[pri[j] * i] = 0;//三次方以上 break; }//如果i遇到了自己最小的质因子就直接跳出 } } } int main() { int t; cin >> t; int x = maxn; N = maxn; init(); getpri(); s[1] = 1; rep(i, 2, x) { s[i] =s[i-1]+ f[i]; } while (t--) { cin >> n; cout << s[n]<< endl; } //cin >> t; return 0; } /* 1 8 20000000 2 5 8 */
原文地址:https://www.cnblogs.com/SuuT/p/9571597.html
时间: 2024-10-10 19:39:18