码迷,mamicode.com
首页 > 其他好文 > 详细

ACM-ICPC 2018 南京赛区网络预赛 - J. Sum (找规律+打表)

时间:2018-09-01 21:50:31      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:++i   出现   res   line   欧拉   stdin   找规律   拆分   --   

题意:\(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\);
\(d\dagger 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\n",res[n]);
    }
    return 0;
}

ACM-ICPC 2018 南京赛区网络预赛 - J. Sum (找规律+打表)

标签:++i   出现   res   line   欧拉   stdin   找规律   拆分   --   

原文地址:https://www.cnblogs.com/xiuwenli/p/9571342.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!