EntropyIncreaser

SDOI2017 数字表格

Dec 15th, 2017
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.84 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3.  
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7.  
  8. typedef long long ll;
  9.  
  10. const int N = 1000010, P = 1e9L + 7, PC = 500010;
  11.  
  12. int pc;
  13. int mu[N], fib[N], prod[N];
  14. int p[PC];
  15. bool f[N];
  16.  
  17. void pre();
  18. void sieve();
  19. int rev(int x);
  20. int mpow(int x, ll k);
  21. void ex_gcd(int a, int b, int& x, int& y);
  22.  
  23. int main() {
  24.     int t, n, m, ans;
  25.     pre();
  26.     scanf("%d", &t);
  27.     while (t--) {
  28.         scanf("%d%d", &n, &m);
  29.         if (n > m)
  30.             swap(n, m);
  31.         ans = 1;
  32.         for (int l = 1, r; l <= n; l = r + 1) {
  33.             r = min(n / (n / l), m / (m / l));
  34.             ans = (ll)ans * mpow((ll)prod[r] * rev(prod[l - 1]) % P, (ll)(n / l) * (m / l)) % P;
  35.         }
  36.         printf("%d\n", ans);
  37.     }
  38.     return 0;
  39. }
  40.  
  41. int mpow(int x, ll k) {
  42.     int ret = 1;
  43.     for (; k; k >>= 1) {
  44.         if (k & 1)
  45.             ret = (ll)ret * x % P;
  46.         x = (ll)x * x % P;
  47.     }
  48.     return ret;
  49. }
  50.  
  51. void ex_gcd(int a, int b, int& x, int& y) {
  52.     if (b == 0) {
  53.         x = 1;
  54.         y = 0;
  55.         return;
  56.     }
  57.     ex_gcd(b, a % b, y, x);
  58.     y -= a / b * x;
  59. }
  60.  
  61. int rev(int a) {
  62.     int x, y;
  63.     ex_gcd(a, P, x, y);
  64.     if (x < 0)
  65.         x += P;
  66.     return x;
  67. }
  68.  
  69. void sieve() {
  70.     mu[1] = 1;
  71.     for (int i = 2; i < N; ++i) {
  72.         if (!f[i]) {
  73.             p[++pc] = i;
  74.             mu[i] = -1;
  75.         }
  76.         for (int j = 1; (ll)i * p[j] < N; ++j) {
  77.             f[i * p[j]] = true;
  78.             mu[i * p[j]] = -mu[i];
  79.             if (i % p[j] == 0) {
  80.                 mu[i * p[j]] = 0;
  81.                 break;
  82.             }
  83.         }
  84.     }
  85. }
  86.  
  87. void pre() {
  88.     sieve();
  89.     fib[1] = 1;
  90.     for (int i = 2; i < N; ++i) {
  91.         fib[i] = fib[i - 1] + fib[i - 2];
  92.         if (fib[i] >= P)
  93.             fib[i] -= P;
  94.     }
  95.     fill(prod, prod + N, 1);
  96.     for (int i = 1; i < N; ++i)
  97.         for (int j = 1; i * j < N; ++j)
  98.             switch (mu[j]) {
  99.             case 1:
  100.                 prod[i * j] = (ll)prod[i * j] * fib[i] % P;
  101.                 break;
  102.             case -1:
  103.                 prod[i * j] = (ll)prod[i * j] * rev(fib[i]) % P;
  104.                 break;
  105.             }
  106.     for (int i = 2; i < N; ++i)
  107.         prod[i] = (ll)prod[i] * prod[i - 1] % P;
  108. }
Advertisement
Add Comment
Please, Sign In to add comment