Cod sursa(job #343934)

Utilizator mgntMarius B mgnt Data 27 august 2009 20:25:38
Problema Indep Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

class Numar {
public:
    Numar();
    ~Numar();
    Numar & operator  = (Numar const & v);
    Numar & operator  = (int v);
    Numar & operator *= (int v);
    Numar & operator += (Numar const & v);
    
    friend ofstream & operator << (ofstream & o, Numar const & v);
    
private:
  int * d_;
    int   n_;
};

Numar::Numar()
: d_(0)
{
}

Numar::~Numar()
{
  if(0!=d_) delete [] d_;
}

Numar &
Numar::operator = (Numar const & v)
{
    if(0!=d_) delete [] d_;
    d_ = new int [2+v.n_];
    n_ = v.n_;
    d_[n_]=0;
    d_[1+n_]=0;
    memcpy(d_, v.d_, n_ * sizeof(d_[0]));
    return *this;
}

Numar &
Numar::operator = (int v) // 0 < v < 1000
{
  if(0 != d_) delete [] d_;
    
    d_ = new int[1];
    d_ [0] = v;
    n_ = 1;
    return * this;
}

Numar &
Numar::operator *= (int v) // 0 < v < 1000
{
    if(0==d_) return * this;
    
    int t = 0;
    int i;
    for(i=0;i<n_ || t;i++) {
      d_[i]=d_[i]*v + t;
        t=d_[i]/1000;
        d_[i]=d_[i]%1000;
    }
    n_ = i;
    return * this;
}

Numar &
Numar::operator += (Numar const & v) { // v <= * this
    int * p, * q, np, nq, * r, i, t;
    if(v.n_ > n_) {
         p=v.d_;
        np=v.n_;
         q = d_;
        nq = n_;
    } else {
         p=d_;
        np=n_;
         q=v.d_;
        nq=v.n_;
    }
    r=new int [1+np];
    t=0;
    for(i=0;i<nq;i++) {
        r[i]=p[i]+q[i]+t;
        t=r[i]/1000;
        r[i]=r[i]%1000;
    }
    for(;i<np || t;i++) {
        r[i]=p[i]+t;
        t=r[i]/1000;
        r[i]=r[i]%1000;
    }
    n_ = i;
    delete d_;
    d_ = r;
    return * this;
}

ofstream & operator << (ofstream & o, Numar const & v) {
  if(0 == v.d_) return o;
    if(1 == v.n_) {
      o<<v.d_[0];
    return o;
    }
    o<<v.d_[-1+v.n_];
    int i;
    for(i=-2+v.n_;i>=0;i--) {
      if(100 > v.d_[i]) o<<0;
        if(10  > v.d_[i]) o<<0;
        o<<v.d_[i];
    }
    return o;
}

int const N=500;
int const M=1000;
int V[N];
Numar C[1+N][1+M];
  // C[s][i] - numarul de siruri pentru care cmmdc este i
  // folosind doar primele s elemente din sir

int
cmmdc (int a, int b) {
  int c;
  while ( a ) {
    c = b % a ;
    b = a ;
    a = c ;
  }
  return b;
}

int
main ( ) {
  ifstream sin("indep.in"); int n, s, k, i, d; Numar unu; unu=1;
  sin>>n; for ( s=0; n>s; ++s ) { sin>>V[s]; }
  for ( s=1; M>=s; ++s ) { C[0][s]=0; }
  for ( s=1; n>=s; ++s ) { k=V[s-1]; 
    for ( i=1; M>=i; ++i ) { C[s][i]=C[s-1][i]; } C[s][k]+=unu;
    for ( i=1; M>=i; ++i ) { d=cmmdc(k,i); C[s][d]+=C[s-1][i]; }
  }
  ofstream sout("indep.out"); sout<<C[n][1]<<endl;
  return 0;
}