QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#476695#9115. Contour Multiplicationucup-team3926#TL 100ms16308kbC++208.3kb2024-07-13 20:47:142024-07-13 20:47:14

Judging History

你现在查看的是最新测评结果

  • [2024-07-13 20:47:14]
  • 评测
  • 测评结果:TL
  • 用时:100ms
  • 内存:16308kb
  • [2024-07-13 20:47:14]
  • 提交

answer

/*
    author:  Maksim1744
    created: 13.07.2024 15:36:44
*/

#include "bits/stdc++.h"

using namespace std;

using ll = long long;
using ld = long double;

#define mp   make_pair
#define pb   push_back
#define eb   emplace_back

#define sum(a)     ( accumulate ((a).begin(), (a).end(), 0ll))
#define mine(a)    (*min_element((a).begin(), (a).end()))
#define maxe(a)    (*max_element((a).begin(), (a).end()))
#define mini(a)    ( min_element((a).begin(), (a).end()) - (a).begin())
#define maxi(a)    ( max_element((a).begin(), (a).end()) - (a).begin())
#define lowb(a, x) ( lower_bound((a).begin(), (a).end(), (x)) - (a).begin())
#define uppb(a, x) ( upper_bound((a).begin(), (a).end(), (x)) - (a).begin())

template<typename T>             vector<T>& operator--            (vector<T> &v){for (auto& i : v) --i;            return  v;}
template<typename T>             vector<T>& operator++            (vector<T> &v){for (auto& i : v) ++i;            return  v;}
template<typename T>             istream& operator>>(istream& is,  vector<T> &v){for (auto& i : v) is >> i;        return is;}
template<typename T>             ostream& operator<<(ostream& os,  vector<T>  v){for (auto& i : v) os << i << ' '; return os;}
template<typename T, typename U> pair<T,U>& operator--           (pair<T, U> &p){--p.first; --p.second;            return  p;}
template<typename T, typename U> pair<T,U>& operator++           (pair<T, U> &p){++p.first; ++p.second;            return  p;}
template<typename T, typename U> istream& operator>>(istream& is, pair<T, U> &p){is >> p.first >> p.second;        return is;}
template<typename T, typename U> ostream& operator<<(ostream& os, pair<T, U>  p){os << p.first << ' ' << p.second; return os;}
template<typename T, typename U> pair<T,U> operator-(pair<T,U> a, pair<T,U> b){return mp(a.first-b.first, a.second-b.second);}
template<typename T, typename U> pair<T,U> operator+(pair<T,U> a, pair<T,U> b){return mp(a.first+b.first, a.second+b.second);}
template<typename T, typename U> void umin(T& a, U b){if (a > b) a = b;}
template<typename T, typename U> void umax(T& a, U b){if (a < b) a = b;}

#ifdef HOME
#define SHOW_COLORS
#include "/mnt/c/Libs/tools/print.cpp"
#else
#define show(...) void(0)
#define debugf(fun)   fun
#define debugv(var)   var
#define mclock    void(0)
#define shows     void(0)
#define debug  if (false)
#define OSTREAM(...)    ;
#define OSTREAM0(...)   ;
#endif

namespace var_mint_ns {
struct VarModular {
    using value_type = int;
  private:
    static value_type P;
  public:
    value_type value;

    VarModular(long long k = 0) : value(norm(k)) {}

    friend VarModular& operator += (      VarModular& n, const VarModular& m) { n.value += m.value; if (n.value >= P) n.value -= P; return n; }
    friend VarModular  operator +  (const VarModular& n, const VarModular& m) { VarModular r = n; return r += m; }

    friend VarModular& operator -= (      VarModular& n, const VarModular& m) { n.value -= m.value; if (n.value < 0)    n.value += P; return n; }
    friend VarModular  operator -  (const VarModular& n, const VarModular& m) { VarModular r = n; return r -= m; }
    friend VarModular  operator -  (const VarModular& n)                      { return VarModular(-n.value); }

    friend VarModular& operator *= (      VarModular& n, const VarModular& m) { n.value = reduce(n.value * 1ll * m.value); return n; }
    friend VarModular  operator *  (const VarModular& n, const VarModular& m) { VarModular r = n; return r *= m; }

    friend VarModular& operator /= (      VarModular& n, const VarModular& m) { return n *= m.inv(); }
    friend VarModular  operator /  (const VarModular& n, const VarModular& m) { VarModular r = n; return r /= m; }

    VarModular& operator ++ (   ) { return *this += 1; }
    VarModular& operator -- (   ) { return *this -= 1; }
    VarModular  operator ++ (int) { VarModular r = *this; *this += 1; return r; }
    VarModular  operator -- (int) { VarModular r = *this; *this -= 1; return r; }

    friend bool operator == (const VarModular& n, const VarModular& m) { return n.value == m.value; }
    friend bool operator != (const VarModular& n, const VarModular& m) { return n.value != m.value; }

    explicit    operator       int() const { return value; }
    explicit    operator      bool() const { return value; }
    explicit    operator long long() const { return value; }

    static value_type           mod()      { return     P; }

    value_type norm(long long k) {
        if (!(-P <= k && k < P)) k %= P;
        if (k < 0) k += P;
        return k;
    }

    VarModular inv() const {
        value_type a = value, b = P, x = 0, y = 1;
        while (a != 0) { value_type k = b / a; b -= k * a; x -= k * y; swap(a, b); swap(x, y); }
        return VarModular(x);
    }

  private:
    static uint64_t m;
  public:
    static void set_mod(value_type mod) {
        m = (__uint128_t(1) << 64) / mod;
        P = mod;
    }

    static value_type reduce(uint64_t a) {
        uint64_t q = ((__uint128_t(m) * a) >> 64);
        a -= q * P;
        if (a >= P)
            a -= P;
        return a;
    }
};
uint64_t VarModular::m = 0;
VarModular pow(VarModular m, long long p) {
    VarModular r(1);
    while (p) {
        if (p & 1) r *= m;
        m *= m;
        p >>= 1;
    }
    return r;
}
VarModular::value_type VarModular::P;
// use "VarModular::set_mod([your value])" later

ostream& operator << (ostream& o, const VarModular& m) { return o << m.value; }
istream& operator >> (istream& i,       VarModular& m) { long long k; i >> k; m.value = m.norm(k); return i; }
string   to_string(const VarModular& m) { return to_string(m.value); }

using Mint = VarModular;
// using Mint = long double;

vector<Mint> f, fi;
void init_C(int n) {
    f.assign(n, 1); fi.assign(n, 1);
    for (int i = 2; i < n; ++i) f[i] = f[i - 1] * i;
    fi.back() = Mint(1) / f.back();
    for (int i = n - 2; i >= 0; --i) fi[i] = fi[i + 1] * (i + 1);
}
Mint C(int n, int k) {
    if (k < 0 || k > n) return 0;
    else return f[n] * fi[k] * fi[n - k];
}
}
using namespace var_mint_ns;

template<class Fun>
class y_combinator_result {
    Fun fun_;
public:
    template<class T>
    explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {}

    template<class ...Args>
    decltype(auto) operator()(Args &&...args) {
        return fun_(std::ref(*this), std::forward<Args>(args)...);
    }
};
template<class Fun>
decltype(auto) y_combinator(Fun &&fun) {
    return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun));
}
// auto gcd = std::y_combinator([](auto gcd, int a, int b) -> int {
//     return b == 0 ? a : gcd(b, a % b);
// });

struct Que {
    int c;
    int d;
    Mint x;

    pair<int, int> who() const {
        return mp(c, d);
    }
};

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL);

    int n;
    cin >> n;
    { int p; cin >> p; VarModular::set_mod(p); }
    int q;
    cin >> q;
    vector<Que> qq(q);
    for (auto& q : qq) {
        cin >> q.c >> q.d >> q.x;
    }

    vector<Mint> ans(1 << n, 1);

    vector<Que> tmp;
    auto solve = y_combinator([&](auto solve, int n, int l, int r, const vector<Que>& que_) {
        tmp.clear();
        for (const auto& q : que_) {
            if (q.d < 0 || q.d > n) continue;
            tmp.pb(q);
        }
        sort(tmp.begin(), tmp.end(), [&](const auto& a, const auto& b) {
            return a.who() < b.who();
        });
        vector<Que> que;
        for (const auto& q : tmp) {
            if (que.empty() || que.back().who() != q.who()) {
                que.pb(q);
            } else {
                que.back().x *= q.x;
            }
        }
        if (n == 0) {
            assert(l == r);
            for (const auto& q : que)
                ans[l] *= q.x;
            return;
        }

        vector<Que> left, right;
        for (const auto& q : que) {
            auto [c, d, x] = q;
            int has_bit = (c >> (n - 1)) & 1;
            left.pb(Que{c, d - has_bit, x});
            right.pb(Que{c, d - !has_bit, x});
        }
        int m = (l + r) / 2;
        solve(n - 1, l, m, left);
        solve(n - 1, m + 1, r, right);
    });

    solve(n, 0, (1 << n) - 1, qq);

    cout << ans << '\n';

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3492kb

input:

3 100 2
0 2 4
3 0 25

output:

1 1 1 0 1 4 4 1 

result:

ok 8 tokens

Test #2:

score: 0
Accepted
time: 0ms
memory: 3556kb

input:

4 998244353 7
0 2 4
3 0 25
9 4 37
4 1 16
6 3 8
1 4 68
13 3 97

output:

1552 8 1 9700 1 64 229696 1 8 4 388 8 64 8 68 1 

result:

ok 16 tokens

Test #3:

score: 0
Accepted
time: 0ms
memory: 3532kb

input:

1 2 1
0 1 696782227

output:

1 1 

result:

ok 2 tokens

Test #4:

score: 0
Accepted
time: 100ms
memory: 16308kb

input:

5 461799503 500000
26 2 741819583
24 4 16805970
5 2 192769861
5 4 365614234
31 0 680795402
23 5 256636931
24 4 150277578
3 1 912506287
27 5 785022824
1 4 645930009
8 2 715559837
3 4 166807726
22 2 584850050
23 1 481241174
7 0 947410124
0 4 588117991
13 5 882053755
16 5 430265734
29 5 324612363
9 4 8...

output:

0 0 45928586 0 134497770 0 206758057 394352068 0 244291949 0 209807785 0 285761102 402778530 0 0 0 61435341 287059619 347978730 135518317 363576818 0 0 0 0 0 0 0 0 349412261 

result:

ok 32 tokens

Test #5:

score: -100
Time Limit Exceeded

input:

13 471577301 500000
6468 6 306578522
8113 3 479854366
720 5 444779113
8132 12 228254993
6354 13 64735677
6877 9 421810792
541 9 278526040
3090 0 986913987
5352 8 16271033
3263 5 929162219
3483 8 459160836
5355 12 867871503
3035 9 877478088
4090 10 88145277
468 6 252659128
4500 6 628030207
455 5 2083...

output:


result: