Pagini recente » Cod sursa (job #1304198) | Cod sursa (job #1480199) | Cod sursa (job #1476149) | Cod sursa (job #3241634) | Cod sursa (job #3265821)
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("primxxl.in");
ofstream fout("primxxl.out");
// x=f1^e1*f2^e2*...*fn^en => Daca exista un factor prim > sqrt(x) atunci el este unic!
// In plus, acest factor va avea exponentul 1(daca ar avea
// exponentul >= 2, atunci f*f > sqrt(x)*sqrt(x) = x, dar
// f^2 divide x, deci este imposibil
// x=f1^e1*...*fn-1^en-1*fn^1 => f1,f2,...fn-1<sqrt(x) si fn>sqrt(x)
const int NRPRIME = 31625;// sqrt(1.000.000.000) ~ 31625
bool ciur[NRPRIME];
int prime[NRPRIME],len=0;
int e2[NRPRIME];//e2[i] = exponentul celui de al i-lea numar prim in descompunerea lui k!
//e2[i] = [k/prim[i]] + [k/prim[i]^2] + [k/prim[i]^3] +...
int main ()
{
// aflam numerele prime prin ciurul lui Eratostene
ciur[0]=ciur[1]=1;
for(int i=2;i*i<=NRPRIME;i++){
if(ciur[i]==0){
for(int j=i*i;j<=NRPRIME;j+=i){
ciur[j]=1;
}
}
}
// punem numerele prim intr-un vector
for(int i=1;i<=NRPRIME;i++){
if(ciur[i]==0){
len++;
prime[len]=i;
}
}
int n,k;
fin>>n>>k;
// precalculam valorile lui e2
for(int i=1;i<=len && prime[i]<=k;i++){
int f=prime[i];
while(k/f!=0){
e2[i]+=k/f;
f*=prime[i];
}
}
int ans=0;
for(int i=1;i<=n;i++){
int x;
int ok=1;// ok = 1 daca x divide k!
fin>>x;
int copy_x=x;
for(int j=1;j<=len && prime[j]*prime[j]<=copy_x;j++){
if(x%prime[j]==0){
int e1=0;
while(x%prime[j]==0){
x/=prime[j];
e1++;
}
/* Observam ca prin precalcularea valorilor lui e2[i] se
salveaza timp prin faptul ca acest while nu se mai executa
pentru ficare x, ci doar o data la inceput
while(k/f!=0){
e2+=k/f;
f*=prime[i];
}
*/
// Pentru ca x sa divida k! => oricare factor prim al lui x
// trebuie sa aiba exponentul mai mic decat al lui k!
if(e1>e2[j]){
ok=0;// x nu divide k! deci ne putem opri
break;
}
}
}
// Dupa ce am trecut prin toti factorii primi mai mici decat sqrt(x)
// la final o sa ne ramana factorul prim mai mare decat sqrt(x) cu
// puterea 1 adica x=f, sau x=1(in cazul in care nu avem niciun f>sqrt(x))
// De asemenea, daca x este numar prim, o sa avem x ul neschimbat in
// acest moment (x=copy_x), de aceea trebuie sa verificam x>k
// Pe scurt, in variabila x o sa fie un numar prim la exponentul 1
// care o sa divida k! doar daca este mai mic decat k
if(x>k){
ok=0;
}
/*
if(ok){
ans++;
}
*/
ans+=ok;// secventa de cod echivalenta cu if ul de mai sus
}
fout<<ans;
}