danielvitor23

Divisor Analysis

Nov 16th, 2021 (edited)
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.50 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int MAX =  1e5+5;
  5. const int64_t MOD = 1e9+7;
  6.  
  7. int64_t phi(int64_t n) {
  8.     int64_t result = n;
  9.     for (int64_t i = 2; i * i <= n; i++) {
  10.         if (n % i == 0) {
  11.             while (n % i == 0)
  12.                 n /= i;
  13.             result -= result / i;
  14.         }
  15.     }
  16.     if (n > 1)
  17.         result -= result / n;
  18.     return result;
  19. }
  20.  
  21. const int64_t MOD2 = phi(MOD);
  22.  
  23. int64_t extendedGcd(int64_t a, int64_t b, int64_t &x, int64_t &y) {
  24.   if (b == 0) {
  25.     x = 1; y = 0;
  26.     return a;
  27.   }
  28.   int64_t g = extendedGcd(b, a%b, y, x);
  29.   y -= x*(a/b);
  30.   return g;
  31. }
  32.  
  33. int64_t modularInverse(int64_t a, int64_t _MOD = MOD) {
  34.   int64_t x, y;
  35.   extendedGcd(a, _MOD, x, y);
  36.   return (x%_MOD + _MOD)%_MOD;
  37. }
  38.  
  39. int64_t modMul(int64_t a, int64_t b, int64_t _MOD = MOD) {
  40.   a %= _MOD; b %= _MOD;
  41.   return (__int128)a*b%_MOD;
  42. }
  43.  
  44. int64_t binpow(int64_t base, int64_t exp) {
  45.   base %= MOD;
  46.   int64_t res = 1;
  47.   while (exp > 0) {
  48.     if (exp & 1) res = modMul(res, base);
  49.     base = modMul(base, base);
  50.     exp >>= 1;
  51.   }
  52.   return res;
  53. }
  54.  
  55. int n;
  56. int64_t x[MAX], k[MAX];
  57.  
  58. int main() {
  59.   cin.tie(0)->sync_with_stdio(0);
  60.  
  61.   // Input
  62.   cin >> n;
  63.   for (int i = 0; i < n; ++i) {
  64.     cin >> x[i] >> k[i];
  65.   }
  66.  
  67.   // Number of divisors
  68.   int64_t numOfDivisors = 1;
  69.   for (int i = 0; i < n; ++i) {
  70.     numOfDivisors = modMul(numOfDivisors, (k[i] + 1));
  71.   }
  72.  
  73.   // Sum of divisors
  74.   int64_t sumOfDivisors = 1;
  75.   for (int i = 0; i < n; ++i) {
  76.     sumOfDivisors = modMul(sumOfDivisors, modMul(binpow(x[i], k[i]+1)-1, modularInverse(x[i]-1)));
  77.   }
  78.  
  79.   bool square = true;  
  80.   // Calculate N
  81.   int64_t N = 1;
  82.   for (int i = 0; i < n; ++i) {
  83.     square &= (k[i] % 2 == 0);
  84.   }
  85.  
  86.   if (square) {
  87.     for (int i = 0; i < n; ++i) {
  88.       N = modMul(N, binpow(x[i], k[i]/2));
  89.     }
  90.   } else {
  91.     for (int i = 0; i < n; ++i) {
  92.       N = modMul(N, binpow(x[i], k[i]));
  93.     }
  94.   }
  95.  
  96.   bool ok = false;
  97.   // Number of divisors by phi(mod)
  98.   int64_t numOfDivisorsPhiMod = 1;
  99.   for (int i = 0; i < n; ++i) {
  100.     if (!ok and (k[i] & 1)) {
  101.       numOfDivisorsPhiMod = modMul(numOfDivisorsPhiMod, (k[i] + 1)/2, MOD2);
  102.       ok = true;
  103.     } else {
  104.       numOfDivisorsPhiMod = modMul(numOfDivisorsPhiMod, (k[i] + 1), MOD2);
  105.     }
  106.   }
  107.  
  108.   // Product of divisors
  109.   int64_t productOfDivisors = 1;
  110.  
  111.   productOfDivisors = binpow(N, numOfDivisorsPhiMod);
  112.  
  113.   cout << numOfDivisors << ' ';
  114.   cout << sumOfDivisors << ' ';
  115.   cout << productOfDivisors << '\n';
  116. }
Add Comment
Please, Sign In to add comment