2020牛客寒假算法基础集训营3 H 牛牛的k合因子数

题目描述

题目连接

合数是指自然数中除了能被1和本身整除外,还能被其他数(0除外)整除的数。 牛牛最近在研究“k合因子数”,所谓“k合数”是指一个数的所有因子中,是合数的因子共有k个。 例如20的因子有1,2,4,5,10,20,其中4,10,20为合数,它有3个合数因子,就称20是一个 “3合因子数” 牛牛想要知道1~n中给定k的情况下k合因子数的数目。

输入描述

第一行输入两个数字n,m(1≤n,m≤105)(1 \leq n,m \leq 10^5)(1≤n,m≤105)表示范围以及查询“k”的数目接下来m行,每行一个正整数k(1≤k≤n)(1 \leq k \leq n)(1≤k≤n)查询k合因子数的数目。

输出描述:

一行一个数字,表示k合因子数的数目

示例1

输入

10 5
1
2
3
4
5

输出

4
1
0
0
0

说明

1~10的范围内1合因子数有:4,6,9,10,共4个2合因子数有:8,共1一个。

思路:打表1-n内的每个数的因数中是合数的数的个数,没啥技术含量。

#include<bits/stdc++.h>
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
typedef long double LD;
const int mod = 1e8 + 7;
const int MAXN = 1e6 + 10;
const int INF = 0x3f3f3f3f;
bool isPrime( ll num )//目前我知道的最快速的素数判断,是素数返回1,合数返回0,这里算1是素数(实际上1不是素数
{
    
    if(num ==2|| num==3||num==1 )   
        return 1 ;
    if(num %6!= 1&&num %6!= 5)  
        return 0 ;
    int tmp =sqrt(num);
    for(int i= 5; i <=tmp; i+=6 )   
        if(num %i== 0||num %(i+ 2)==0) 
            return 0 ;
    return 1 ;
}
int num(ll n){ //分解出这个数的所搜因子
    int count=0;//对因子中的合数计数
    if(!isPrime(n))count++;//n是本身的因子,如果n是合数,合数个数加一
    for(int i=2;i<=sqrt(n);i++){
        if(n%i==0){如果n整除i
            if(i==sqrt(n) && n/i==i&&!isPrime(i)){ //如果i是n的开根号,且i是合数
                 count++;   
            }
            else{
            	 if(!isPrime(i))count++;//对i这个因子判断
            	 if(!isPrime(n/i))count++;//再对另一个因子判断
			}
        }
    }
    return count;
}
ll a[MAXN],cnt[MAXN],x;
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
	    cnt[num(i)]++;//打表
	}
	for(int i=1;i<=m;i++)
	{
		cin>>x;
		cout<<cnt[x]<<endl;
	}
	
 } 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值