ACM-ICPC 2018 南京赛区网络预赛 J. Sum [ 筛法 + 数论 + 二分 ]

题目链接:

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

题意概括:

没有平方数因子的整数叫 square-free integer。把 i 分解为两个square-free integer,乘积为 i , 这两个数可以相同

定义 F(i) 表示 i 不同分解方式的数目,求

 \sum^n_1f(i)

数据范围:

T\leq20

n\leq 2*10^{7}

题解分析:

这里换一个思路,不求某个数可以有几种分解方式,而是拿 square-free integers 来组合成范围内的数。

比如当 n = 10 , 则所有的 square-free integers 是 1、2、3、5、6、7、10 

对于 2 和 3 ,乘积为 6 < 10 ,则可认为找到了 6 的一种分解方式

一种思路是:需要求出所有的两两组合,若乘积小于 n , 则贡献了一种分解方式

但这样复杂度 O(n^{2}) ,肯定会 TLE 。

正确的做法:

先打表求出所有的 square-free integer ,由于在表内是单调递增的,所以先确定左端的起点,再用二分找到相乘小于 n 的位置

这段区间的长度,就是新贡献的分解方式数目。

AC代码:

#include <stdio.h>
#include <math.h>
#include <memory.h>
#include <algorithm>
using namespace std;
const int MAXN = 2e7 + 10;
int num[MAXN], cnt = 0;
bool vis[MAXN];

void Get_num(int x, int y) {
    int k = sqrt(y + 0.5);
    memset(vis, 0, sizeof(vis));
    for(int i = 2; i <= k; i++){
        for(int j = i * i; j <= y; j += i * i) {
            if(j >= x) {
                vis[j] = 1;
            }
        }
    }
    for(int i = 1; i <= y - x + 1; i++)
        if(!vis[i])
            num[cnt++] = i;//找没有被更新(筛)到的数
}

int main () {
    int T;
    Get_num(1, MAXN - 1);
    scanf("%d", &T);
    while (T --) {
        int n, ans = 0;
        scanf("%d", &n);
        for (int i = 0; i < cnt; i ++) {
            if (num[i] * num[i] > n)  break;
            ans++;
        
            int key = n / num[i], *pos;
            
            if (key > num[cnt - 1])
                ans += (cnt - i - 1) * 2;
            else {
                pos = lower_bound(num + i, num + cnt, key);
                if (*pos > key) pos --;
                int temp = (int)(pos - (num + i));
                ans += temp * 2;
            }
        }
        printf("%d\n", ans);
    }
}

 

                                                                  Sum

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*2 is 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=ab and n=ba are considered different if a̸=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 \sum^n_1f(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 \sum^n_1f(i).

Hint

\sum^8_1=f(i)=f(1)+⋯+f(8)
=1+2+2+1+2+4+2+0=14

样例输入

2
5
8

样例输出

8
14

题目来源

ACM-ICPC 2018 南京赛区网络预赛

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章