danielvitor23

Divisor Analysis

Nov 16th, 2021
1,072
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.43 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.   // Product of divisors
  80.   int64_t productOfDivisors = 1;
  81.  
  82.   vector<int64_t> pref(n), suff(n);
  83.   pref[0] = k[0] + 1;
  84.   suff[n-1] = k[n-1] + 1;
  85.  
  86.   for (int i = 1; i < n; ++i) {
  87.     pref[i] = modMul(pref[i-1], (k[i] + 1), MOD2);
  88.   }
  89.   for (int i = n-2; i >= 0; --i) {
  90.     suff[i] = modMul(suff[i+1], (k[i] + 1), MOD2);
  91.   }
  92.  
  93.   for (int i = 0; i < n; ++i) {
  94.     int64_t aux1 = 1;
  95.     if (i > 0) aux1 = pref[i-1];
  96.     if (i < n-1) aux1 = modMul(aux1, suff[i+1], MOD2);
  97.     int64_t aux2 = 0;
  98.     if (k[i] & 1) {
  99.       aux2 = modMul(k[i], (k[i]+1)/2, MOD2);
  100.     } else {
  101.       aux2 = modMul(k[i]/2, k[i]+1, MOD2);
  102.     }
  103.     productOfDivisors = modMul(productOfDivisors, binpow(x[i], modMul(aux1, aux2, MOD2)));
  104.   }
  105.  
  106.   cout << numOfDivisors << ' ';
  107.   cout << sumOfDivisors << ' ';
  108.   cout << productOfDivisors << '\n';
  109. }
Advertisement
Add Comment
Please, Sign In to add comment