Cod sursa(job #797644)

Utilizator vendettaSalajan Razvan vendetta Data 14 octombrie 2012 16:00:50
Problema Light2 Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.38 kb
#include <iostream>
#include <fstream>

using namespace std;

#define Kmax 22
#define ll long long

ifstream f("light2.in");
ofstream g("light2.out");

ll n, K, a[Kmax], Log[1<<Kmax];
ll  Cmmmc[1<<Kmax];

void citeste(){

   f >> n;
   f >> K;
   for(int i=1; i<=K; ++i) f >> a[i];

}

ll cmmdc(ll x, ll y){

   for(ll rest; y!=0; rest=x%y, x=y, y=rest);

   return x;

}

void rezolva(){

   //le fac pe alea cu un bit

   ll rez = 0;
   for(int i=0; i<K; ++i){
      Cmmmc[(1<<i)] = a[i+1];
      rez += n / a[i+1];//sa vad cati multiplii are a[i]; a. i. a[i]*k <= n
   }

   Log[1] = 1;
   for(int i=2; i<=(1<<K); ++i) Log[i] = Log[i/2] + (i%2);

   for(int conf=2; conf<(1LL<<K); ++conf){
      if (Log[conf] == 1LL) continue;
      for(int i=K; i>=0; --i){
         if ( (conf & (1<<i) ) != 0){
            int prev = conf - (1<<i);
            Cmmmc[conf] = (Cmmmc[prev] * a[i+1]) / (cmmdc(Cmmmc[prev], a[i+1]));
            int cnt = Log[conf];//cati biti de 1 are conf;
            //cout << Cmmmc[conf] << " " << conf << "\n";
            if ( (cnt % 2) != 0){
               rez += n / Cmmmc[conf] * (1<<(cnt-1));
            }else rez -= n / Cmmmc[conf] * (1<<(cnt-1));
            break;
         }

      }
   }

   g << rez << "\n";

}

int main(){

   citeste();
   rezolva();

   f.close();
   g.close();

   return 0;

}