Mai intai trebuie sa te autentifici.

Cod sursa(job #2894848)

Utilizator tibinyteCozma Tiberiu-Stefan tibinyte 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;

}