题目链接:
题意概括:
没有平方数因子的整数叫 square-free integer。把 i 分解为两个square-free integer,乘积为 i , 这两个数可以相同
定义 F(i) 表示 i 不同分解方式的数目,求
数据范围:
题解分析:
这里换一个思路,不求某个数可以有几种分解方式,而是拿 square-free integers 来组合成范围内的数。
比如当 n = 10 , 则所有的 square-free integers 是 1、2、3、5、6、7、10
对于 2 和 3 ,乘积为 6 < 10 ,则可认为找到了 6 的一种分解方式
一种思路是:需要求出所有的两两组合,若乘积小于 n , 则贡献了一种分解方式
但这样复杂度 ,肯定会 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 .
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⋅).
Output
For each test case, print the answer .
Hint
=f(i)=f(1)+⋯+f(8)
=1+2+2+1+2+4+2+0=14
样例输入
2
5
8
样例输出
8
14