Skip to content

Commit 966a297

Browse files
authored
Merge pull request #381 from hitonanode/wavelet-matrix
add wavelet matrix
2 parents e546ae8 + 1d558ee commit 966a297

File tree

5 files changed

+588
-0
lines changed

5 files changed

+588
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#define PROBLEM "https://yukicoder.me/problems/no/3207"
2+
#include "../wavelet_matrix.hpp"
3+
#include "../../number/modint_mersenne61.hpp"
4+
5+
#include <iostream>
6+
using namespace std;
7+
8+
using mint = ModIntMersenne61;
9+
10+
int main() {
11+
cin.tie(nullptr), ios::sync_with_stdio(false);
12+
int H, W, N;
13+
cin >> H >> W >> N;
14+
15+
const mint Bx{31979713531853};
16+
const mint By{23599715123};
17+
18+
vector<mint> weights(10);
19+
for (int v : {1, 2, 5, 8, 6, 9}) weights[v] = mint(998244353).pow(v);
20+
21+
wavelet_matrix<int> wm1, wm2;
22+
23+
vector<tuple<int, int, int>> points;
24+
for (int t = 0; t < N; ++t) {
25+
int i, j, x;
26+
cin >> i >> j >> x;
27+
if (x == 0) continue;
28+
--i, --j;
29+
30+
wm1.add_point(i, j);
31+
wm2.add_point(H - 1 - i, W - 1 - j);
32+
33+
points.emplace_back(i, j, x);
34+
}
35+
wm1.build();
36+
wm2.build();
37+
38+
vector dp1(wm1.D(), vector<mint>(wm1.N() + 1));
39+
vector dp2(wm2.D(), vector<mint>(wm2.N() + 1));
40+
41+
for (auto [i, j, x] : points) {
42+
const mint wx = weights.at(x) * Bx.pow(i) * By.pow(j);
43+
wm1.apply(i, j, [&dp1, &wx](int d, int idx) { dp1[d][idx + 1] += wx; });
44+
45+
int y = x;
46+
if (x == 6 or x == 9) y = x ^ (6 ^ 9);
47+
48+
const mint wy = weights.at(y) * Bx.pow(H - 1 - i) * By.pow(W - 1 - j);
49+
wm2.apply(H - 1 - i, W - 1 - j, [&dp2, &wy](int d, int idx) { dp2[d][idx + 1] += wy; });
50+
}
51+
52+
for (auto &v : dp1) {
53+
for (int i = 1; i < (int)v.size(); ++i) v[i] += v[i - 1];
54+
}
55+
for (auto &v : dp2) {
56+
for (int i = 1; i < (int)v.size(); ++i) v[i] += v[i - 1];
57+
}
58+
59+
int Q;
60+
cin >> Q;
61+
while (Q--) {
62+
int l, d, r, u;
63+
cin >> l >> d >> r >> u;
64+
--l, --d;
65+
66+
mint ans1{0}, ans2{0};
67+
wm1.prod(l, r, u, [&ans1, &dp1](int d, int l0, int r0) { ans1 += dp1[d][r0] - dp1[d][l0]; });
68+
wm1.prod(l, r, d, [&ans1, &dp1](int d, int l0, int r0) { ans1 -= dp1[d][r0] - dp1[d][l0]; });
69+
70+
wm2.prod(H - r, H - l, W - d,
71+
[&ans2, &dp2](int d, int l0, int r0) { ans2 += dp2[d][r0] - dp2[d][l0]; });
72+
wm2.prod(H - r, H - l, W - u,
73+
[&ans2, &dp2](int d, int l0, int r0) { ans2 -= dp2[d][r0] - dp2[d][l0]; });
74+
75+
if (ans1 * Bx.pow(H - r) * By.pow(W - u) == ans2 * Bx.pow(l) * By.pow(d)) {
76+
puts("Yes");
77+
} else {
78+
puts("No");
79+
}
80+
}
81+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/point_add_rectangle_sum"
2+
#include "../../segmenttree/binary_indexed_tree.hpp"
3+
#include "../wavelet_matrix.hpp"
4+
#include <iostream>
5+
using namespace std;
6+
7+
int main() {
8+
cin.tie(nullptr), ios::sync_with_stdio(false);
9+
int N, Q;
10+
cin >> N >> Q;
11+
12+
wavelet_matrix<int> wm;
13+
vector<tuple<int, int, int>> points(N);
14+
vector<tuple<int, int, int, int, int>> queries(Q);
15+
16+
for (auto &[i, j, x] : points) {
17+
cin >> i >> j >> x;
18+
wm.add_point(i, j);
19+
}
20+
21+
for (auto &[tp, a, b, c, d] : queries) {
22+
cin >> tp;
23+
if (tp == 0) {
24+
cin >> a >> b >> c;
25+
d = -1;
26+
wm.add_point(a, b);
27+
} else {
28+
cin >> a >> b >> c >> d;
29+
}
30+
}
31+
32+
wm.build();
33+
34+
vector weights(wm.D(), BIT<long long>(wm.N()));
35+
36+
for (auto [i, j, x] : points) {
37+
wm.apply(i, j, [&weights, x](int d, int idx) { weights[d].add(idx, x); });
38+
}
39+
40+
for (auto [tp, l, d, r, u] : queries) {
41+
if (tp == 0) {
42+
wm.apply(l, d, [&weights, r](int d, int idx) { weights[d].add(idx, r); });
43+
} else {
44+
long long ans = 0;
45+
wm.prod(l, r, u,
46+
[&weights, &ans](int d, int l0, int r0) { ans += weights[d].sum(l0, r0); });
47+
wm.prod(l, r, d,
48+
[&weights, &ans](int d, int l0, int r0) { ans -= weights[d].sum(l0, r0); });
49+
cout << ans << '\n';
50+
}
51+
}
52+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/rectangle_sum"
2+
#include "../wavelet_matrix.hpp"
3+
#include <iostream>
4+
using namespace std;
5+
6+
int main() {
7+
cin.tie(nullptr), ios::sync_with_stdio(false);
8+
int N, Q;
9+
cin >> N >> Q;
10+
11+
wavelet_matrix<int> wm;
12+
vector<tuple<int, int, int>> points(N);
13+
for (auto &[i, j, x] : points) {
14+
cin >> i >> j >> x;
15+
wm.add_point(i, j);
16+
}
17+
18+
wm.build();
19+
20+
vector weights(wm.D(), vector<long long>(wm.N() + 1));
21+
for (auto [i, j, x] : points) {
22+
wm.apply(i, j, [&weights, x](int d, int idx) { weights[d][idx + 1] += x; });
23+
}
24+
25+
for (auto &v : weights) {
26+
for (int i = 1; i < (int)v.size(); ++i) v[i] += v[i - 1];
27+
}
28+
29+
while (Q--) {
30+
int l, d, r, u;
31+
cin >> l >> d >> r >> u;
32+
33+
long long ans = 0;
34+
wm.prod(l, r, u, [&weights, &ans](int d, int l0, int r0) {
35+
ans += weights[d][r0] - weights[d][l0];
36+
});
37+
wm.prod(l, r, d, [&weights, &ans](int d, int l0, int r0) {
38+
ans -= weights[d][r0] - weights[d][l0];
39+
});
40+
41+
cout << ans << '\n';
42+
}
43+
}

0 commit comments

Comments
 (0)