ACM-ICPC 2018 南京赛区网络预赛 J(Sum)

https://nanti.jisuanke.com/t/30999

A square-free integer is an integer which is indivisible by any square number except 1. For example, 6=2⋅3 is square-free, but 12=2^2*3⋅ is not, because 2^2is a square number. Some integers could be decomposed into product of two square-free integers, there may be more than one decomposition ways. For example, 6=1⋅6=6⋅1=2⋅3=3⋅2,n=a*b and n=b*a are considered different if a̸=ba \not = ba̸=b. f(n) is the number of decomposition ways that n=ab such that a and b are square-free integers. The problem is calculating ∑i=1nf(i)\sum_{i = 1}^nf(i)∑i=1n​f(i).

Input

The first line contains an integer T(T≤20),denoting the number of test cases.

For each test case, there first line has a integer n(n≤2⋅10^7)

Output

For each test case, print the answer ∑i=1nf(i)\sum_{i = 1}^n f(i)∑i=1n​f(i).

Hint

∑i=18f(i)=f(1)+⋯+f(8)\sum_{i = 1}^8 f(i)=f(1)+ \cdots +f(8)∑i=18​f(i)=f(1)+⋯+f(8)
=1+2+2+1+2+4+2+0=14=1+2+2+1+2+4+2+0=14=1+2+2+1+2+4+2+0=14.

这个题可以理解为对f(n)中,n这个数进行质因子分解,只要有一个质数的质数大于2,那么这个数f(n)就是0,

如果质因子的指数为1,那么就为2,如果指数为2,那么就为1,比如(2^1*3^2)=2*1=2;

题目要求1~2*10^7的f(n),那么只能进行递推,如果我们知道了n的最小值因子是p的话,

n可以表示为n=p^x * y,如果x==1,那么n=2*f(y),

如果x==2,那么n=1*f(y);     如果x>2,那么n=0

扫描二维码关注公众号,回复: 3125099 查看本文章

我们可以使用线性筛法找到一个数的最小质因子

#include<bits/stdc++.h>
using namespace std;
#define maxn 20000010
int prime[maxn],minprime[maxn],tot,n;
long long a[maxn];
void getprime(int N)
{
   memset(prime,0,sizeof(prime));
    for(int i=2;i<=N;i++){
        if(!prime[i]){
            prime[++prime[0]]=i;
            minprime[i]=i;
        }
        for(int j=1;j<=prime[0];j++){
                if(i*prime[j]>maxn)
                break;
            prime[i*prime[j]]=1;
            minprime[i*prime[j]]=prime[j];
            if(i%prime[j]==0)
                break;
        }
    }
}
int main()
{
    a[0]=0;
    a[1]=1;
    getprime(maxn);
    for(int i=2;i<=maxn;i++){
        int p=minprime[i];
        if((long long)p*p*p<maxn&&i%(p*p*p)==0)
            a[i]=0;
        else if((long long)p*p<maxn&&i%(p*p)==0)
            a[i]=a[i/p/p];
        else a[i]=2*a[i/p];
    }
    for(int i=1;i<=maxn;i++)
        a[i]=a[i-1]+a[i];
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        printf("%lld\n",a[n]);
    }
}

猜你喜欢

转载自blog.csdn.net/curry___/article/details/82430478