Advertisement
Guest User

Untitled

a guest
Mar 29th, 2020
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.15 KB | None | 0 0
  1. #include <fstream>
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <cstring>
  7. #include <cstdlib>
  8. #include <ctime>
  9. #include <iomanip>
  10. #include <map>
  11. #include <set>
  12. #include <unordered_map>
  13. #include <unordered_set>
  14. #include <queue>
  15. #include <climits>
  16. #include <bitset>
  17. #include <cassert>
  18.  
  19. using namespace std;
  20.  
  21. const int SIZE = 1 << 17;
  22.  
  23. int pointer = SIZE;
  24. char buffer[SIZE];
  25.  
  26. char Advance() {
  27.     if (pointer == SIZE) {
  28.         fread(buffer, 1, SIZE, stdin);
  29.         pointer = 0;
  30.     }
  31.     return buffer[pointer++];
  32. }
  33.  
  34. int Read() {
  35.     int answer = 0,sign = 1;
  36.     char ch = Advance();
  37.     while (!isdigit(ch) && ch != '-')
  38.         ch = Advance();
  39.     if (ch == '-') {
  40.         ch = Advance();
  41.         sign = -1;
  42.     }
  43.     while (isdigit(ch)) {
  44.         answer = answer * 10 + ch - '0';
  45.         ch = Advance();
  46.     }
  47.     return answer * sign;
  48. }
  49.  
  50. char ReadCh() {
  51.     char ch = Advance();
  52.     while (!isalpha(ch))
  53.         ch = Advance();
  54.     return ch;
  55. }
  56.  
  57. const int MOD = 163577857;
  58. const int ROOT = 23;
  59. const int BASE[23] = {1, 163577856, 140097645, 154888078, 33972488, 4648319, 64472632, 49730547, 21586495, 44400052, 33342237, 103671029, 51270679, 28076510, 119736284, 85042834, 127424876, 80300307, 100999243, 36916096, 121844538, 40336560, 121532577};
  60. const int MAXN = 1000000;
  61. const int MAXNFFT = 1048576;
  62.  
  63. int answer[MAXNFFT], first[MAXNFFT], second[MAXNFFT], other[MAXNFFT];
  64. int factorial[1 + MAXN], inverse[1 + MAXN];
  65.  
  66. void Add(int &x, int y) {
  67.     x += y;
  68.     if (x >= MOD)
  69.         x -= MOD;
  70. }
  71.  
  72. int RaiseToPower(int base, int power) {
  73.     int answer = 1;
  74.     while (power) {
  75.         if (power % 2)
  76.             answer = (1LL * answer * base) % MOD;
  77.         base = (1LL * base * base) % MOD;
  78.         power /= 2;
  79.     }
  80.     return answer;
  81. }
  82.  
  83. void Precompute(int n) {
  84.     factorial[0] = inverse[0] = 1;
  85.     for (int i = 1; i <= n; i++)
  86.         factorial[i] = (1LL * factorial[i - 1] * i) % MOD;
  87.     inverse[n] = RaiseToPower(factorial[n], MOD - 2);
  88.     for (int i = n - 1; i >= 1; i--)
  89.         inverse[i] = (1LL * (i + 1) * inverse[i + 1]) % MOD;
  90. }
  91.  
  92. int Combinations(int n, int k) {
  93.     int answer = (1LL * inverse[n - k] * inverse[k]) % MOD;
  94.     answer = (1LL * answer * factorial[n]) % MOD;
  95.     return answer;
  96. }
  97.  
  98. int BitReversal(int x, int bits) {
  99.     int answer = 0;
  100.     for (int i = 0; i < bits; i++) {
  101.         answer = 2 * answer + x % 2;
  102.         x /= 2;
  103.     }
  104.     return answer;
  105. }
  106.  
  107. void FFT(int *a, int n, bool inverted) {
  108.     int bits = 0;
  109.     while (1 << (bits + 1) <= n)
  110.         bits++;
  111.     for (int i = 0; i < n; i++) {
  112.         int j = BitReversal(i, bits);
  113.         if (j > i)
  114.             swap(a[i], a[j]);
  115.     }
  116.     for (int step = 1; step < n; step *= 2) {
  117.         int omega = BASE[22];
  118.         if (inverted)
  119.             omega = RaiseToPower(omega, MOD - 2);
  120.         omega = RaiseToPower(omega, (1 << 22) / (2 * step));
  121.         for (int i = 0; i < n; i += 2 * step) {
  122.             int power = 1;
  123.             for (int j = i; j < i + step; j++) {
  124.                 int u = a[j], v = (1LL * power * a[j + step]) % MOD;
  125.                 a[j] = u + v;
  126.                 if (a[j] >= MOD)
  127.                     a[j] -= MOD;
  128.                 a[j + step] = u - v;
  129.                 if (a[j + step] < 0)
  130.                     a[j + step] += MOD;
  131.                 power = (1LL * power * omega) % MOD;
  132.             }
  133.         }
  134.     }
  135.     if (inverted) {
  136.         int divide = RaiseToPower(n, MOD - 2);
  137.         for (int i = 0; i < n; i++)
  138.             a[i] = (1LL * a[i] * divide) % MOD;
  139.     }
  140. }
  141.  
  142. void Multiply(int a[], int b[], int c[], int p) {
  143.     int n = 1;
  144.     while (n < 2 * p)
  145.         n *= 2;
  146.     for (int i = p; i < n; i++)
  147.         a[i] = b[i] = 0;
  148.     FFT(a, n, false);
  149.     FFT(b, n, false);
  150.     for (int i = 0; i < n; i++)
  151.         c[i] = (1LL * a[i] * b[i]) % MOD;
  152.     FFT(c, n, true);
  153. }
  154.  
  155. void Solve(int n) {
  156.     if (n == 1) {
  157.         answer[0] = answer[1] = 1;
  158.         return;
  159.     }
  160.     Solve(n / 2);
  161.     for (int i = 0; i <= n / 2; i++)
  162.         first[i] = (1LL * answer[i] * factorial[n / 2 - i]) % MOD;
  163.     int power = 1;
  164.     for (int i = 0; i <= n / 2; i++) {
  165.         second[i] = (1LL * power * inverse[i]) % MOD;
  166.         power = (1LL * power * (n / 2)) % MOD;
  167.     }
  168.     Multiply(first, second, other, n / 2 + 1);
  169.     for (int i = 0; i <= n / 2; i++)
  170.         other[i] = (1LL * other[i] * inverse[n / 2 - i]) % MOD;
  171.     Multiply(answer, other, answer, n / 2 + 1);
  172.     if (n % 2) {
  173.         answer[n] = (1LL * answer[n - 1] * n) % MOD;
  174.         for (int i = n - 1; i >= 1; i--)
  175.             Add(answer[i], (1LL * n * answer[i - 1]) % MOD);
  176.     }
  177. }
  178.  
  179. int main() {
  180.     //freopen("tema.in", "r", stdin);
  181.     //freopen("tema.out", "w", stdout);
  182.     int tests;
  183.     scanf("%d", &tests);
  184.     Precompute(MAXN);
  185.     for (int test = 1; test <= tests; test++) {
  186.         int n, k;
  187.         scanf("%d%d", &n, &k);
  188.         memset(answer, 0, sizeof(answer));
  189.         Solve(n);
  190.         int sum = 0;
  191.         for (int i = 1; i <= k; i++)
  192.             Add(sum, (1LL * answer[i] * Combinations(k - 1, i - 1)) % MOD);
  193.         printf("%d\n", sum);
  194.     }
  195.  
  196.     return 0;
  197. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement