題目鏈接:
題意概括:
沒有平方數因子的整數叫 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