快速切题 sgu117. Counting 分解质因数

117. Counting

time limit per test: 0.25 sec. 
memory limit per test: 4096 KB

 

Find amount of numbers for given sequence of integer numbers such that after raising them to the M-th power they will be divided by K.

 

Input

Input consists of two lines. There are three integer numbers N, M, K (0<N, M, K<10001) on the first line. There are N positive integer numbers − given sequence (each number is not more than 10001) − on the second line.

 

Output

Write answer for given task.

 

Sample Input

4 2 50
9 10 11 12

Sample Output

1
用时:30min
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxnum=10001;
bool isntprime[maxnum];
int prime[maxnum],cnt;
int divide[maxnum][15],num[maxnum],len[maxnum][15];//divide[i][j]为分解i得到的第j个质数 len[i][j]为分解i得到的第j个质数在i中出现的次数 num[i]为分解i得到的质因数个数
int n,m,k;
void calc(){
    cnt=0;
    for(int i=2;i<maxnum;i++){
        if(!isntprime[i]){
            prime[cnt++]=i;
            divide[i][0]=i;
            num[i]=1;
            len[i][0]=1;
            for(int j=i+i;j<maxnum;j+=i){
                isntprime[j]=true;
                divide[j][num[j]]=i;
                int tmp=j;
                while(tmp%i==0){
                    tmp/=i;
                    len[j][num[j]]++;
                }
                num[j]++;
            }
        }
    }
}

int main(){
    calc();
    scanf("%d%d%d",&n,&m,&k);
    if(k==1){printf("%d",n);return 0;}
    int ans=0;
    for(int i=0;i<n;i++){
        int tmp;
        scanf("%d",&tmp);
        bool fl=true;
        for(int j=0;j<num[k];j++){
                int fnd=(lower_bound(divide[tmp],divide[tmp]+num[tmp],divide[k][j]))-divide[tmp];
                if(fnd>=num[tmp]){fl=false;break;}
                if(divide[tmp][fnd]!=divide[k][j]){fl=false;break;}
                if(len[tmp][fnd]*m<len[k][j]){fl=false;break;}
        }
        if(fl)ans++;
    }
    printf("%d\n",ans);
    return 0;
}

  

原文地址:https://www.cnblogs.com/xuesu/p/4004500.html