列表

详情


NC228989. 冷静

描述

想去实现宏大的梦想 向着那遥不可及的地方
想在那一片纯白的世界 留下我最初的脚印
在世界的终端 太阳在永不停息地运转
南风终将吹过小岛 轻抚我的柔发
想去实现心底小小的梦
——《ハルカトオク》
痛定思痛,奋楫争先再出发……
q 次询问。每次询问给定 n 和 K,问 1 ~ n 中有多少数可以表示为大于等于 K 的质数的乘积(一个数可以乘多次)。

输入描述

第一行读入一个整数q 
接下来q行每行读入2个整数,第i行表示 n_iK_i

输出描述

q行,共 q 个数,分别表示 q 次询问的答案。

示例1

输入:

1
100 5

输出:

32

示例2

输入:

2
20 3
10 5

输出:

9
2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 1566ms, 内存消耗: 63108K, 提交时间: 2021-12-25 22:48:12

#include<bits/stdc++.h>
using namespace std;
const int N=3e6+100;
int cnt[N],num[N],ans[N];
struct node{
	int n,k,pos;
}w[N];

inline void pre()
{
	for(int i=2;i<=3000010;i++)
	{
		for(int j=i;j<=3000010;j+=i)
			if(!num[j])
				num[j]=i;
	}
}

inline int cmp(node s1,node s2)
{
	return s1.n<s2.n;
}

inline void update(int x)
{
	for(int i=x;i<=3000010;i+=(i&(-i)))
		cnt[i]+=1;
}

inline int query(int x)
{
	int sum=0;
	for(int i=x;i;i-=(i&(-i)))
		sum+=cnt[i];
	return sum;
}

int main()
{
	pre();
	int q;
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
		scanf("%d%d",&w[i].n,&w[i].k),w[i].pos=i;
	sort(w+1,w+1+q,cmp);
	
	int x=2;
	for(int i=1;i<=q;i++)
	{
		while(x<=w[i].n)
		{
			update(num[x]);
			x++;
		}
		ans[w[i].pos]=w[i].n-query(w[i].k-1)-1;
	}
	
	for(int i=1;i<=q;i++)
		printf("%d\n",ans[i]);
	return 0;
}

上一题