Advertisement

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

阅读量:

一个无平方因子的整数是指其不能被任何大于1的平方数整除的整数。例如6=2×3是一个无平方因子的数;但12=2²×3则不是一个无平方因子的数目因它含有2²这个平方因子。
某些整数可以分解为两个无平方因子数目相乘的形式,并且可能存在多种不同的分解方式。
例如6=1×6=6×1=2×3=3×2,
其中n=ab和n=ba被视为不同的分解情况当a≠b时。
设f(n)表示满足n=ab的所有分解情况数目,
其中a和b均为无平方因子数目,
我们的目标就是计算∑_{i=1}^n f(i).

Input

The initial line includes an integer T(T\le 20), which represents the count of test cases.

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

Output

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

Hint

\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.

样例输入复制

复制代码

样例输出复制

复制代码

题目来源

第20届ACM-ICPC国际 Collegiate Programming Contest(中国)南京赛区网络预赛

题意:定义f[i]i可分割成两个非平方因数之数量(考虑顺序的情况),并计算其前缀和。

思路:对于任意整数n≥1来说,在其素因子分解中可表示为n = a₁{p₁}·a₂{p₂}·…·aₙ^{pₙ}的形式。若其中存在某个指数p_i满足p_i ≥ 3,则函数f(n)的值为零;反之则f(n)等于2的(所有指数p_i=1的情况之和)次幂。该性质可以通过素因子分解的线性筛选法来证明。

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 typedef long long ll;
    
 const int maxn =  2e7+10;
    
 bool check[maxn];
    
 int prime[maxn];
    
 ll f[maxn];
    
 int tot=0;
    
 int main(){
    
     check[1] = 1;
    
     f[1] = 1;
    
     int num;
    
     for(int i=2;i<maxn;i++){
    
     if(check[i]==0){  //prime
    
         prime[tot++]=i;
    
         f[i] = 2;
    
     }
    
     for(int j = 0;j<tot&&(ll)i*prime[j]<maxn;++j)
    
     {
    
         num = i*prime[j];
    
         check[num] = 1;
    
         if(i%prime[j])
    
         {
    
             f[num] = f[i]*2;
    
         }
    
         else if((ll)i%(prime[j]*prime[j])==0)
    
         {
    
             f[num] = 0;
    
         }
    
         else
    
         {
    
             f[num] = f[num/prime[j]/prime[j]];
    
             break;
    
         }
    
     }
    
     }
    
     for(int i = 2;i<maxn;i++)
    
     f[i] += f[i-1];
    
     int t;
    
     int n;
    
     scanf("%d",&t);
    
     while(t--)
    
     {
    
     scanf("%d",&n);
    
     printf("%lld\n",f[n]);
    
     }
    
 }

全部评论 (0)

还没有任何评论哟~