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

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=1n​f(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=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.

题意:

令F(i)表示满足x*y=i,且x和y都不包含平方数因子的合法(x,y)对数,求∑F(i)

思路:

容易发现∑F(i) n > 0等价于(非质数的平凡的倍数 )相乘小于或等于n的方案。 比如对于当n = 8,等价于1,2,3,5,6,7这六个数两两相乘并且相乘结果小于8的种类的个数 ,比如1 * 1 , 1 * 2 , 1 * 3 , 1 * 5 , 1 * 6, 1 * 7 , 2 * 1 , 2 * 2 , 2 * 3 , 3 * 1 , 3 * 2 , 5 * 1 , 6 * 1 , 7 * 1 。共14种。

于是我们可以筛掉质数的平方的倍数,再求非质数的平方的倍数的前缀和(学长说时间复杂度是o(n)的),又因为1 * 2 和2 * 1 等价,所以后面可以优化下变成 O(2n + t * sqrt(n)),又因为题目的t很小,所以方法可行。

#include <iostream> 
#include <cstdio> 
#include <fstream> 
#include <algorithm> 
#include <cmath> 
#include <deque> 
#include <vector> 
#include <queue> 
#include <string> 
#include <cstring> 
#include <map> 
#include <stack> 
#include <set> 
int ans[20000009];
bool tmp[20000009];
const int MAXN=5009;
bool flag[MAXN];
int primes[MAXN/3],pi;
void prime() {
	int i,j;
	pi=0;
	memset(flag,false,sizeof(flag));
	for(i=2; i<MAXN; i++) {
		if(!flag[i]) primes[pi++]=i;
		for(j=0; (j < pi) && (i*primes[j] < MAXN); j++) {
			flag[i * primes[j]] = true;
			if(i % primes[j]==0) break;//保证非素数只筛一次
		}
	}
}
int main() {
	prime();
	for(int i = 2;i < 5000;i++){
		if(flag[i] == false){//如果他是质数,筛掉其平方的倍数 
			for(int j = i * i;j <= 20000000;j += i * i){
				tmp[j] = true;
			}
		}
	}
	ans[0] = 0;
	for(int i = 1;i < 20000009;i++){//求前缀和 
		ans[i] = ans[i - 1];
		if(tmp[i] == false){
			ans[i]++;
		}
	}
//	for(int i = 1;i < 50;i++){
//		printf("%d ",ans[i]);
//	}
	int t,n;
	scanf("%d",&t);
	while(t--){
		long long answer = 0;
		scanf("%d",&n);
		for(int i = 1;i <= n / i;i++){
			if(tmp[i] != true){
				answer += (ans[n / i] - ans[i]) * 2 + 1;
			}
		}
		printf("%lld\n",answer);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值