J. Sum
A square-free integer is an integer which is indivisible by any square number except 11. For example, 6 = 2 \cdot 36=2⋅3 is square-free, but 12 = 2^2 \cdot 312=22⋅3 is not, because 2^222 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\cdot 6=6 \cdot 1=2\cdot 3=3\cdot 2, n=ab6=1⋅6=6⋅1=2⋅3=3⋅2,n=ab and n=ban=ba are considered different if a \not = ba̸=b. f(n)f(n) is the number of decomposition ways that n=abn=ab such that aa and bb are square-free integers. The problem is calculating \sum_{i = 1}^nf(i)∑i=1nf(i).
Input
The first line contains an integer T(T\le 20)T(T≤20), denoting the number 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=1nf(i).
Hint
\sum_{i = 1}^8 f(i)=f(1)+ \cdots +f(8)∑i=18f(i)=f(1)+⋯+f(8)
=1+2+2+1+2+4+2+0=14=1+2+2+1+2+4+2+0=14.
题意:
令F(i)表示满足x*y=i,且x和y都不包含平方数因子的合法(x,y)对数,求∑F(i)
思路:
很容易证明F(i)是积性函数,如果i中不存在3次方以上的质因子,F(i) = 2^(i中只出现一次的质因子个数),否则F(i) = 0
那么就是个积性函数前缀和的问题了
很多项都为0,利用Min_25筛可以在1s内轻松解决范围内的所有询问
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
#define er 500000004
int cnt, s[200005], id[200005], B, m, h[200005];
bool flag[200005];
LL n, w[200005], pri[200005];
void Primeset(int n)
{
int i, j;
for(i=2;i<=n;i++)
{
if(flag[i]==0)
{
pri[++cnt] = i;
s[cnt] = s[cnt-1]+i;
}
for(j=1;j<=cnt&&i*pri[j]<=n;j++)
{
flag[i*pri[j]] = 1;
if(i%pri[j]==0)
break;
}
}
}
LL F(LL x, int y)
{
LL t1;
int i, k, e, ans;
if(x<=1 || pri[y]>x)
return 0;
if(x>B)
k = n/x;
if(x<=B)
k = id[x];
ans = 2*(h[k]-(y-1));
for(i=y;i<=cnt&&(LL)pri[i]*pri[i]<=x;i++)
{
t1 = pri[i];
for(e=1;t1*pri[i]<=x;e++)
{
if(e==1)
ans = (ans+(F(x/t1, i+1)*2+1));
else if(e==2)
ans = (ans+F(x/t1, i+1));
t1 *= pri[i];
}
}
return ans;
}
int main(void)
{
LL i, j, k, last;
int T;
scanf("%d", &T);
while(T--)
{
m = cnt = 0;
scanf("%lld", &n);
B = sqrt(n), Primeset(B);
for(i=1;i<=n;i=last+1)
{
w[++m] = n/i;
h[m] = w[m]-1;
last = n/(n/i);
if(n/i<=B)
id[n/i] = m;
}
for(j=1;j<=cnt;j++)
{
for(i=1;i<=m&&pri[j]*pri[j]<=w[i];i++)
{
if(w[i]/pri[j]<=B)
k = id[w[i]/pri[j]];
else
k = n/(w[i]/pri[j]);
h[i] = h[i]-(h[k]-(j-1));
}
}
printf("%lld\n", (F(n, 1)+1));
}
return 0;
}