Cod sursa(job #645344)

Utilizator tak3rStefan Mirea tak3r Data 9 decembrie 2011 12:27:35
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include<cstdio>
#include<vector>
#include<complex>
#include<cstring>

#define BIG_NUMBER 9973

using namespace std;

vector<int> primes;

void getPrimes( int n ){
  long long i,j;
  char marked[ n/2+1 ];
  
  memset( marked, 0, sizeof( marked ) / sizeof( char ) );
  
  primes.clear();
  primes.push_back( 2 );
  
  for( i=3; i<=n; i+=2 ){
    if( 0 == marked[i/2+1] ){
      primes.push_back( i );
      for( j=i*i; j<=n; j+=i*2 ){
        if( 0 == marked[j/2+1] && j % i == 0 ){
          marked[j/2+1] = 1;
        }
      }
    }
  }
}

vector< pair<long,int> > get_divisors_power( long long n ){
  int i, num;
  vector< pair<long,int> > v;
  
  num = 0;
  while( n % 2 == 0 ){
    ++num;
    n /= 2;
  }
  if( num > 0 ){
    v.push_back( make_pair( 2, num ) );
  }

  for( i=0; primes[i] <= n && i < primes.size(); ++i ){
    num = 0;
    while( n % primes[i] == 0 ){
      ++num;
      n /= primes[i];
    }
    if( num > 0 ){
      v.push_back( make_pair( primes[i], num ) );
    }
  }

  /*
  for( i=3; i<=2*n; i+=2 ){
    num = 0;
    while( n % i == 0 ){
      ++num;
      n /= i;
    }
    if( num > 0 ){
      v.push_back( make_pair( i, num ) );
    }
  }
  */
  return v;
}

pair<int,long long> backtrack( 
    int index, 
    long long P, 
    vector< pair<long, int> > v 
  ){
  if( index >= v.size() ){
    return make_pair( 1, (long long) P );
  } else {
    long long prod = 1;
    int s = 0;
    int n = 0;
    for( int i=0; i<=v[index].second; ++i ){
      pair<int, long long> back = backtrack( index+1, P*prod, v );
      n += back.first;
      s += (back.second % BIG_NUMBER);
      prod *= v[index].first;
    }
    return make_pair( n, s % BIG_NUMBER );
  }
}

void ssnd( long long n ){
  vector< pair<long,int> > v = get_divisors_power( n );
  pair<int, int> sn = backtrack( 0, 1, v );
  printf("%d %d\n", sn.first, sn.second );
}

int main(){
  
  freopen( "ssnd.in", "r", stdin );
  freopen( "ssnd.out", "w", stdout );
  
  int n,i;
  long long tmp;
  
  getPrimes( 1 * 1000 * 1000 );
  
  scanf( "%d", &n );
  for( i=0; i<n; ++i ){
    scanf( "%lld", &tmp );
    ssnd( tmp );
  }
  
  return 0;
  
}