Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <algorithm>
- #include <vector>
- #include <cassert>
- using namespace std;
- typedef long long ll;
- /*struct cmplx {
- double x, y;
- cmplx() { x = y = 0; }
- cmplx(dbl x_, dbl y_) : x(x_), y(y_) {}
- };
- inline cmplx operator+(cmplx a, cmplx b) { return cmplx(a.x + b.x, a.y + b.y); }
- inline cmplx operator-(cmplx a, cmplx b) { return cmplx(a.x - b.x, a.y - b.y); }
- inline cmplx operator*(cmplx a, cmplx b) { return cmplx(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }
- inline cmplx conj(cmplx a) { return cmplx(a.x, -a.y); }*/
- const int mod = 786433;
- const int root = 3;
- const int root_rev = 524289;
- const int root_pw = 1 << 18;
- pair<int, int> ext_gcd(int a, int b)
- {
- if (b == 0)
- return {1, 0};
- auto ans = ext_gcd(b, a % b);
- return {ans.second, ans.first - (a / b) * ans.second};
- }
- int reverse(int a)
- {
- int ans = ext_gcd(a, mod).first;
- ans %= mod;
- if (ans < 0)
- ans += mod;
- return ans;
- }
- void bit_reverse(vector<int>& a, int n, int q)
- {
- int rev[n];
- rev[0] = 0;
- for (int j = 1; j < n; j++)
- rev[j] = ((rev[j >> 1]) >> 1) ^ ((j & 1) << (q - 1));
- for (int j = 0; j < n; j++)
- if (j < rev[j])
- swap(a[j], a[rev[j]]);
- }
- void fft (vector<int>& a, int n, int q, bool is_inverse) {
- int w = is_inverse ? root_rev : root;
- bit_reverse(a, n, q);
- for (int len = 2; len <= n; len <<= 1)
- {
- int wlen = w;
- for (int i = len; i < root_pw; i <<= 1)
- wlen = (int)((ll)wlen * wlen % mod);
- for (int i = 0; i < n; i += len)
- {
- int x = 1;
- for (int j = 0; j < len / 2; j++) {
- int u = a[i + j];
- int v = (int)((ll)a[i + j + len/2] * x % mod);
- a[i + j] = (u + v) % mod;
- a[i + j + len/2] = (u - v + mod) % mod;
- x = (int)((ll)x * wlen % mod);
- }
- }
- }
- if (is_inverse)
- {
- int nrev = (reverse(n) + mod) % mod;
- for (int i = 0; i < n; i++)
- a[i] = (int)(((ll)a[i] * nrev) % mod);
- }
- }
- vector<int> operator+(const vector<int>& a, const vector<int>& b)
- {
- vector<int> sum;
- sum.assign(max(a.size(), b.size()), 0);
- for (int i = 0; i < (int)a.size(); i++)
- sum[i] += a[i];
- for (int i = 0; i < (int)b.size(); i++)
- sum[i] = (sum[i] + b[i]) % mod;
- return sum;
- }
- vector<int> operator*(int x, const vector<int>& a)
- {
- vector<int> prod(a);
- for (int i = 0; i < (int)a.size(); i++)
- prod[i] = (prod[i] * x) % mod;
- return prod;
- }
- vector<int> operator*(const vector<int>& a, const vector<int>& b)
- {
- cout << "{ ";
- for (int el: a)
- cout << el << " ";
- cout << "}" << endl;
- cout << "*" << endl;
- cout << "{ ";
- for (int el: a)
- cout << el << " ";
- cout << "}" << endl;
- vector<int> fa(a);
- vector<int> fb(b);
- size_t n = 1, q = 0;
- size_t k = a.size(), m = b.size();
- for (; n < k + m + 1; n <<= 1 , q += 1);
- fa.resize(n);
- fb.resize(n);
- fft(fa, n, q, false), fft (fb, n, q, false);
- for (size_t i = 0; i < n; i++)
- fa[i] *= fb[i];
- fft (fa, n, q, true);
- cout << "=\n{ ";
- for (int el: fa)
- cout << el << " ";
- cout << "}" << endl << endl;
- return fa;
- }
- int main()
- {
- size_t n;
- int h;
- cin >> n >> h;
- vector<int> a, b, c;
- a = {1};
- b = {0, 1};
- for (int i = 2; i <= h; i++)
- {
- c = b * b + 2 * a * b;
- a = b;
- b = c;
- cout << "#" << i << ": ";
- for (int j: b)
- cout << j << " ";
- cout << endl;
- }
- cout << (b.size() < n + 1) ? 0 : b[n] % mod;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement