Advertisement
sarker306

UVa 12425

Mar 18th, 2012
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.26 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. #define SIZE 1000002LL
  5. #define SQRTSIZE 1001
  6. #define MAXFACTORS 4097
  7. #define PRIMESTOSIZE 78500
  8.  
  9. long arrPhi[SIZE], primes[PRIMESTOSIZE], numberOfPrimes, numberOfFactors;
  10. char isNotPrime[SIZE];
  11. long long factors[MAXFACTORS + 1], tempFactors[1 + (MAXFACTORS >> 1) ], arr[MAXFACTORS+2];
  12.  
  13. void initArrays(){
  14.     long i, j;
  15.    
  16.     for ( i = 0 ; i < SIZE ; i++ ) arrPhi[i] = i;
  17.     for ( i = 2 ; i < SIZE ; i+=2 ) arrPhi[i] >>= 1;
  18.    
  19.     primes[numberOfPrimes++] = 2;
  20.     for ( i = 3 ; i < SIZE ; i+=2 ){
  21.         if ( isNotPrime[i>>1] == 0 ){
  22.             if ( i < SQRTSIZE )
  23.                 for ( j = i * i ; j < SIZE ; j += i<<1 )
  24.                     isNotPrime[j>>1] = 1;
  25.            
  26.             primes[numberOfPrimes++] = i;
  27.             for ( j = i ; j < SIZE ; j+=i )
  28.                 arrPhi[j] -= arrPhi[j]/i;
  29.         }
  30.     }
  31. }
  32.  
  33. long long phi( long long n ){
  34.     long long m = n;
  35.     long i;
  36.    
  37.     if ( n < SIZE ) return arrPhi[n];
  38.     for ( i = 0 ; i < numberOfPrimes && n > 1 ; i++ ){
  39.         if( n % primes[i] == 0){
  40.             do{
  41.                  n /= primes[i];
  42.             }while( n % primes[i] == 0);
  43.             m -= m / primes[i];
  44.         }
  45.        
  46.         if ( n < SIZE && isNotPrime[n>>1] == 0 ) break;
  47.     }
  48.    
  49.     if ( n > 1 ) m -= m / n;
  50.     return m;
  51. }
  52.  
  53. long lowerBound(long long *arr, long n, long long num ){
  54.     long low = 0, high = n, mid;
  55.    
  56.     while ( low + 1 < high ) {
  57.         mid = ( low + high ) >> 1;
  58.         if ( arr[mid] > num ) high = mid;
  59.         else low = mid;
  60.     }
  61.    
  62.     return low;
  63. }
  64.  
  65. void factorize(long long n){
  66.     long i, j, k = 0, limit = (int)(sqrt(n) + 0.5);
  67.    
  68.     /* factorize n */
  69.     for ( i = 1 ; i <= limit ; i++ ){
  70.         if ( n % i == 0 ){
  71.             factors[k] = i, tempFactors[k] = n/i;
  72.             k++;
  73.         }
  74.     }
  75.    
  76.     j = k - 1;
  77.     if ( factors[k-1] == tempFactors[k-1] ) j--;
  78.     for ( ; j >=0 ; j--, k++ ) factors[k] = tempFactors[j];
  79.     factors[k] = 1LL<<63; /* dummy, used for lowerbound */
  80.     /* TODO (mooo#1#): Need to factorize numbers using prime factors, to
  81.                        reduce time */
  82.     numberOfFactors = k;
  83. }
  84.  
  85. void precalculateNumbersForQueries(long long n){
  86.     long i, j;
  87.    
  88.     factorize(n);
  89.     /* find number of values with gcd( value, n ) <= factor[i]
  90.        multiply all "proper" coprimes of n/factors[i] = factors[nums - i - 1]
  91.        with factor[i],
  92.        then the gcd will be equal to factor[i].
  93.     */
  94.     arr[0] = phi(n);
  95.     for ( i = 1, j = numberOfFactors - 2 ; i < numberOfFactors ; i++, j-- ){
  96.         arr[i] = arr[i-1] + phi(factors[j]);
  97.     }
  98.    
  99.     arr[i] = arr[i-1]; /* dummy, used in case input x > n */
  100. }
  101.  
  102. int main(){
  103.     long long n, x;
  104.     long query, kase, tests;
  105.    
  106.     initArrays();
  107.     scanf("%ld", &tests);
  108.     for( kase = 1 ; kase <= tests ; kase++ ){
  109.         scanf("%lld", &n);
  110.         precalculateNumbersForQueries(n);
  111.         printf("Case %ld\n", kase);
  112.         scanf("%ld", &query);
  113.         while( query-- ){
  114.             scanf("%lld", &x);
  115.             if ( x < 1 ){
  116.                 printf("0\n");
  117.                 continue;
  118.             }
  119.             printf("%lld\n", arr[lowerBound(factors, numberOfFactors, x)]);
  120.         }
  121.     }
  122.    
  123.     return 0;
  124. }
  125. /* test with 200560490130 */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement