QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#318774 | #7561. Digit DP | Isrothy | WA | 732ms | 22508kb | C++23 | 4.5kb | 2024-01-31 20:12:21 | 2024-01-31 20:12:21 |
Judging History
answer
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iostream>
constexpr int mod = 998244353;
constexpr int M = 105;
using int128_t = __int128;
using uint128_t = unsigned __int128;
constexpr int64_t c3(int64_t n) {
return static_cast<int64_t>((int128_t(n) * (n - 1) * (n - 2) / 6 % mod));
}
constexpr int64_t c2(int64_t n) {
return static_cast<int64_t>(n * (n - 1) / 2 % mod);
}
struct data {
int s0, s1, s2, s3;
explicit data(int s0 = 0, int s1 = 0, int s2 = 0, int s3 = 0)
: s0(s0), s1(s1), s2(s2), s3(s3) {}
data add(int64_t x) const {
auto x2 = x * x % mod;
auto x3 = x2 * x % mod;
return data(
s0,
static_cast<int>((s1 + s0 * x) % mod),
static_cast<int>((s2 + x * (s0 - 1) % mod * s1 + x2 * c2(s0)) % mod),
static_cast<int>(
(s3 + x * (s0 - 2) * s2 % mod + x2 * c2(s0 - 1) % mod * s1 % mod + x3 * c3(s0) % mod
)
% mod
)
);
}
};
data merge(const data &l, const data &r) {
return data(
(l.s0 + r.s0) % mod,
(l.s1 + r.s1) % mod,
static_cast<int>((l.s2 + r.s2 + (int64_t) l.s1 * r.s1) % mod),
static_cast<int>((l.s3 + r.s3 + (int64_t) l.s1 * r.s2 + (int64_t) l.s2 * r.s1) % mod)
);
}
data s[M];
int a[M];
int n;
struct tree {
data v{};
tree *ls, *rs;
int lazy;
void push_up() {
v = merge(ls->v, rs->v);
}
tree(data v, tree *ls, tree *rs) : v(v), ls(ls), rs(rs), lazy(0) {}
tree(int64_t prefix, int depth) : v(s[depth].add(prefix)), ls(nullptr), rs(nullptr), lazy(0){};
void push_down(int64_t pl, int64_t pr, int depth) {
if (!ls) {
ls = new tree(pl, depth);
}
if (!rs) {
rs = new tree(pr, depth);
}
if (lazy) {
ls->v = ls->v.add(lazy);
ls->lazy = (ls->lazy + lazy) % mod;
rs->v = rs->v.add(lazy);
rs->lazy = (rs->lazy + lazy) % mod;
lazy = 0;
}
}
};
auto query(tree *&p, uint128_t l, uint128_t r, uint128_t _l, uint128_t _r, int prefix, int depth) {
assert(p);
if (l == _l && r == _r) {
return p->v;
}
auto pl = prefix;
auto pr = (prefix + a[depth]) % mod;
auto mid = (l + r) >> 1;
p->push_down(pl, pr, depth + 1);
if (_r <= mid) {
return query(p->ls, l, mid, _l, _r, pl, depth + 1);
}
if (_l > mid) {
return query(p->rs, mid + 1, r, _l, _r, pr, depth + 1);
}
return merge(
query(p->ls, l, mid, _l, mid, pl, depth + 1),
query(p->rs, mid + 1, r, mid + 1, _r, pr, depth + 1)
);
}
std::ostream &operator<<(std::ostream &os, uint128_t x) {
if (x <= 9) {
os << (int) x;
return os;
}
os << (x / 10) << (int) (x % 10);
return os;
}
void update(
tree *&p, uint128_t l, uint128_t r, uint128_t _l, uint128_t _r, int prefix, int depth, int x
) {
assert(p);
if (l == _l && r == _r) {
p->v = p->v.add(x);
p->lazy = (p->lazy + x) % mod;
return;
}
auto pl = prefix;
auto pr = (prefix + a[depth]) % mod;
auto mid = (l + r) >> 1;
p->push_down(pl, pr, depth + 1);
if (_r <= mid) {
update(p->ls, l, mid, _l, _r, pl, depth + 1, x);
} else if (mid < _l) {
update(p->rs, mid + 1, r, _l, _r, pr, depth + 1, x);
} else {
update(p->ls, l, mid, _l, mid, pl, depth + 1, x);
update(p->rs, mid + 1, r, mid + 1, _r, pr, depth + 1, x);
}
p->push_up();
}
int main() {
int n, q;
scanf("%d%d", &n, &q);
for (int i = 0; i < n; ++i) {
scanf("%d", a + i);
}
std::reverse(a, a + n);
s[n] = data(1, 0);
for (int i = n - 1; i >= 0; --i) {
s[i] = merge(s[i + 1].add(a[i]), s[i + 1]);
}
auto root = new tree(0, 0);
while (q--) {
int op;
char sl[200], sr[200];
scanf("%d%s%s", &op, sl, sr);
uint128_t l = 0, r = 0;
for (int i = 0; i < n; ++i) {
l = l << 1 | sl[i] - '0';
r = r << 1 | sr[i] - '0';
}
if (op == 1) {
int x;
scanf("%d", &x);
update(root, 0, ((uint128_t) 1 << n) - 1, l, r, 0, 0, x);
} else {
printf("%d\n", (query(root, 0, ((uint128_t) 1 << n) - 1, l, r, 0, 0).s3 + mod) % mod);
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 4104kb
input:
3 3 1 2 4 2 000 111 1 010 101 1 2 000 111
output:
1960 3040
result:
ok 2 number(s): "1960 3040"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3812kb
input:
2 2 1 1 2 00 10 2 00 11
output:
0 2
result:
ok 2 number(s): "0 2"
Test #3:
score: -100
Wrong Answer
time: 732ms
memory: 22508kb
input:
99 49952 470888 74578 802746 396295 386884 721198 628655 722503 207868 647942 87506 792718 761498 917727 843338 908043 952768 268783 375312 414369 319712 96230 277106 168102 263554 936674 246545 667941 198849 268921 191459 436316 134606 802932 515506 837311 465964 394766 17626 650419 984050 790137 4...
output:
885225704 514073326 468806216 572704291 437831901 156264944 55780215 943772491 863709942 422748194 574190999 247879930 924612989 11159311 431119241 950611227 779673220 723984799 465952289 323391190 706531929 63622555 228154 617780473 327834230 287680613 203909188 392040212 19922658 589092409 7128215...
result:
wrong answer 1st numbers differ - expected: '413449847', found: '885225704'