1 ~ n 中有多少数可以表示为大于等于 K 的质数的乘积
链接:https://ac.nowcoder.com/acm/contest/11216/G
来源:牛客网
痛定思痛,奋楫争先再出发……
q 次询问。每次询问给定 n 和 K,问 1 ~ n 中有多少数可以表示为大于等于 K 的质数的乘积(一个数可以乘多次)。
输入描述:
链接:https://ac.nowcoder.com/acm/contest/11216/G
来源:牛客网
第一行读入一个整数q
接下来q行每行读入2个整数,第i行表示 nin_iniKiK_iKi
1≤q≤3e61 \leq q\le 3e61≤q≤3e6,1≤ni,Ki≤3e61 \leq n_i,K_i\le 3e61≤ni,Ki≤3e6。
输出描述:
q行,共 q 个数,分别表示 q 次询问的答案。
示例2
输出
复制9 2
转化题意,会发现求的就是数的最小质因子大于等于 KK 的数个数。
开一个树状数组,从小到大,加入每个数的最小质因子。将询问挂在 nn 上,查询即可。
#include<iostream> #include<algorithm> using namespace std; const int maxn=3e6+100; int p[maxn]; int vis[maxn]; int z[maxn]; int cnt=0; int c[maxn],ans[maxn]; int lowbit(int x){ return x&-x; } struct node{ int n,k; int id; bool friend operator<(node a,node b){ return a.n<b.n; } }save[maxn]; void get_prime(){ for(int i=2;i<maxn;i++){ if(!vis[i]){ p[++cnt]=i; z[i]=i; } for(int j=1;j<=cnt&&i*p[j]<maxn;j++){ vis[i*p[j]]=1; z[i*p[j]]=p[j]; if(i%p[j]==0){ break; } } } } void add(int x){ for(int i=x;i<maxn;i+=lowbit(i)){ c[i]+=1; } } int get(int x){ int ans=0; for(int i=x;i>0;i-=lowbit(i)){ ans+=c[i]; } return ans; } int main(){ get_prime(); int m; cin>>m; for(int i=1;i<=m;i++){ scanf("%d%d",&save[i].n,&save[i].k); save[i].id=i; } sort(save+1,save+m+1); int l=1; for(int i=1;i<=m;i++){ while(l<save[i].n){ add(z[++l]); } ans[save[i].id]=save[i].n-1-get(save[i].k-1); } for(int i=1;i<=m;i++){ cout<<ans[i]<<"\n"; } }