快速切题 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; }