QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#318666 | #7561. Digit DP | Isrothy | WA | 702ms | 22520kb | C++23 | 6.3kb | 2024-01-31 16:42:21 | 2024-01-31 16:42: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;
template<typename T>
T power(T x, T k) {
T res(1);
for (; k; k >>= 1) {
if (k & 1) {
res = res * x % mod;
}
x = x * x % mod;
}
return res;
}
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 + x2 * c2(s0 - 1) % mod * s1 + x3 * c3(s0)) % mod
)
);
}
data mul(int64_t x) const {
auto x2 = x * x % mod;
auto x3 = x2 * x % mod;
return data(
s0,
static_cast<int>((s1 * x) % mod),
static_cast<int>((s2 * x2) % mod),
static_cast<int>((s3 * x3) % 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];
int64_t 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) {
return;
}
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, int64_t prefix, int depth
) {
/* if (!p) { */
/* p = new tree(prefix, depth); */
/* } */
if (l == _l && r == _r) {
return p->v;
}
auto pl = prefix;
auto pr = (prefix + a[depth]) % mod;
p->push_down(pl, pr, depth + 1);
auto mid = (l + r) >> 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,
int64_t prefix,
int depth,
int64_t x
) {
/* if (!p) { */
/* p = new tree(prefix, depth); */
/* } */
/* assert(p); */
/* std::cerr << l << " " << r << " " << _l << " " << _r << " " << prefix << " " << depth */
/* << std::endl; */
if (l == _l && r == _r) {
p->v = p->v.add(x);
p->lazy = static_cast<int>((p->lazy + x) % mod);
return;
}
auto pl = prefix;
auto pr = (prefix + a[depth]) % mod;
/* puts("wow"); */
p->push_down(pl, pr, depth + 1);
auto mid = (l + r) >> 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("%lld", 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 t = s[n].add(a[n - 1]); */
/* fprintf(stderr, "t = %d %d %d %d\n", t.s0, t.s1, t.s2, t.s3); */
/* } */
/* { */
/* auto f = [&](int x) { */
/* int64_t res = 1; */
/* for (int i = 0; i < n; ++i) { */
/* if (x >> i & 1) { */
/* res = res * a[i] % mod; */
/* } */
/* } */
/* return res; */
/* }; */
/* int64_t sum = 0; */
/* for (int i = 0; i < 1 << n; ++i) { */
/* for (int j = i + 1; j < 1 << n; ++j) { */
/* for (int k = j + 1; k < 1 << n; ++k) { */
/* sum = (sum + f(i) + f(j) + f(k)) % mod; */
/* } */
/* } */
/* } */
/* fprintf(stderr, "sum = %lld\n", sum); */
/* for (int i = 0; i <= n; ++i) { */
/* fprintf(stderr, "s[%d] = %d %d %d %d\n", i, s[i].s0, s[i].s1, s[i].s2, s[i].s3); */
/* } */
/* } */
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: 3828kb
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: 3836kb
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: 702ms
memory: 22520kb
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:
591354622 640451152 325661507 580867983 195134189 977690611 229653421 515543640 456234713 277404887 64601170 414890 378873553 196181462 365184913 570079294 127018203 356663707 403036453 550290737 464255545 844501038 323052431 215084102 173581973 14808535 961784547 114932699 152892612 629501135 95173...
result:
wrong answer 1st numbers differ - expected: '413449847', found: '591354622'