Mai intai trebuie sa te autentifici.
Cod sursa(job #2894848)
Utilizator | Data | 28 aprilie 2022 14:39:40 | |
---|---|---|---|
Problema | Flux maxim | Scor | 0 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva educationala | Marime | 6.39 kb |
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, mod;
struct modint {
int32_t value;
modint() = default;
modint(int32_t value_) : value(value_% mod) {}
modint(int64_t value_) : value(value_% mod) {}
inline modint operator + (modint other) const { int32_t c = this->value + other.value; return modint(c >= mod ? c - mod : c); }
inline modint operator - (modint other) const { int32_t c = this->value - other.value; return modint(c < 0 ? c + mod : c); }
inline modint operator * (modint other) const { int32_t c = (int64_t)this->value * other.value % mod; return modint(c < 0 ? c + mod : c); }
inline modint& operator += (modint other) { this->value += other.value; if (this->value >= mod) this->value -= mod; return *this; }
inline modint& operator -= (modint other) { this->value -= other.value; if (this->value < 0) this->value += mod; return *this; }
inline modint& operator *= (modint other) { this->value = (int64_t)this->value * other.value % mod; if (this->value < 0) this->value += mod; return *this; }
inline modint operator - () const { return modint(this->value ? mod - this->value : 0); }
modint pow(int32_t k) const { modint x = *this, y = 1; for (; k; k >>= 1) { if (k & 1) y *= x; x *= x; } return y; }
modint inv() const { return pow(mod - 2); } // MOD must be a prime
inline modint operator / (modint other) const { return *this * other.inv(); }
inline modint operator /= (modint other) { return *this *= other.inv(); }
inline bool operator == (modint other) const { return value == other.value; }
inline bool operator != (modint other) const { return value != other.value; }
inline bool operator < (modint other) const { return value < other.value; }
inline bool operator > (modint other) const { return value > other.value; }
};
modint operator * (int64_t value, modint n) { return modint(value) * n; }
modint operator * (int32_t value, modint n) { return modint(value) * n; }
istream& operator >> (istream& in, modint& n) { return in >> n.value; }
ostream& operator << (ostream& out, modint n) { return out << n.value; }
struct combi {
int n; vector<modint> facts, finvs, invs;
combi(int _n) : n(_n), facts(_n), finvs(_n), invs(_n) {
facts[0] = finvs[0] = 1;
invs[1] = 1;
for (int i = 2; i < n; i++) invs[i] = invs[mod % i] * (-mod / i);
for (int i = 1; i < n; i++) {
facts[i] = facts[i - 1] * i;
finvs[i] = finvs[i - 1] * invs[i];
}
}
inline modint fact(int n) { return facts[n]; }
inline modint finv(int n) { return finvs[n]; }
inline modint inv(int n) { return invs[n]; }
inline modint ncr(int n, int k) { return n < k or k < 0 ? 0 : facts[n] * finvs[k] * finvs[n - k]; }
inline modint aranj(int n, int k) { return ncr(n, k) * facts[k]; }
};
struct base {
double x, y;
base() { x = y = 0; }
base(double x, double y) : x(x), y(y) { }
};
inline base operator + (base a, base b) { return base(a.x + b.x, a.y + b.y); }
inline base operator - (base a, base b) { return base(a.x - b.x, a.y - b.y); }
inline base operator * (base a, base b) { return base(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }
inline base conj(base a) { return base(a.x, -a.y); }
int lim = 1;
vector<base> roots = { {0, 0}, {1, 0} };
vector<int> rev = { 0, 1 };
const double PI = acosl(-1.0);
void ensure_base(int p) {
if (p <= lim) return;
rev.resize(1 << p);
for (int i = 0; i < (1 << p); i++) rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (p - 1));
roots.resize(1 << p);
while (lim < p) {
double angle = 2 * PI / (1 << (lim + 1));
for (int i = 1 << (lim - 1); i < (1 << lim); i++) {
roots[i << 1] = roots[i];
double angle_i = angle * (2 * i + 1 - (1 << lim));
roots[(i << 1) + 1] = base(cos(angle_i), sin(angle_i));
}
lim++;
}
}
void fft(vector<base>& a, int n = -1) {
if (n == -1) n = a.size();
assert((n & (n - 1)) == 0);
int zeros = __builtin_ctz(n);
ensure_base(zeros);
int shift = lim - zeros;
for (int i = 0; i < n; i++) if (i < (rev[i] >> shift)) swap(a[i], a[rev[i] >> shift]);
for (int k = 1; k < n; k <<= 1) {
for (int i = 0; i < n; i += 2 * k) {
for (int j = 0; j < k; j++) {
base z = a[i + j + k] * roots[j + k];
a[i + j + k] = a[i + j] - z;
a[i + j] = a[i + j] + z;
}
}
}
}
vector<int> multiply(vector<int>& a, vector<int>& b, int eq = 0) {
int need = a.size() + b.size() - 1;
int p = 0;
while ((1 << p) < need) p++;
ensure_base(p);
int sz = 1 << p;
vector<base> A, B;
if (sz > (int)A.size()) A.resize(sz);
for (int i = 0; i < (int)a.size(); i++) {
int x = (a[i] % mod + mod) % mod;
A[i] = base(x & ((1 << 15) - 1), x >> 15);
}
fill(A.begin() + a.size(), A.begin() + sz, base{ 0, 0 });
fft(A, sz);
if (sz > (int)B.size()) B.resize(sz);
if (eq) copy(A.begin(), A.begin() + sz, B.begin());
else {
for (int i = 0; i < (int)b.size(); i++) {
int x = (b[i] % mod + mod) % mod;
B[i] = base(x & ((1 << 15) - 1), x >> 15);
}
fill(B.begin() + b.size(), B.begin() + sz, base{ 0, 0 });
fft(B, sz);
}
double ratio = 0.25 / sz;
base r2(0, -1), r3(ratio, 0), r4(0, -ratio), r5(0, 1);
for (int i = 0; i <= (sz >> 1); i++) {
int j = (sz - i) & (sz - 1);
base a1 = (A[i] + conj(A[j])), a2 = (A[i] - conj(A[j])) * r2;
base b1 = (B[i] + conj(B[j])) * r3, b2 = (B[i] - conj(B[j])) * r4;
if (i != j) {
base c1 = (A[j] + conj(A[i])), c2 = (A[j] - conj(A[i])) * r2;
base d1 = (B[j] + conj(B[i])) * r3, d2 = (B[j] - conj(B[i])) * r4;
A[i] = c1 * d1 + c2 * d2 * r5;
B[i] = c1 * d2 + c2 * d1;
}
A[j] = a1 * b1 + a2 * b2 * r5;
B[j] = a1 * b2 + a2 * b1;
}
fft(A, sz); fft(B, sz);
vector<int> res(need);
for (int i = 0; i < need; i++) {
long long aa = A[i].x + 0.5;
long long bb = B[i].x + 0.5;
long long cc = A[i].y + 0.5;
res[i] = (aa + ((bb % mod) << 15) + ((cc % mod) << 30)) % mod;
}
return res;
}
int32_t main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n >> mod;
}