

Ac ơi, giúp em giải bài này vs ạ. C++ hoặc Python, 5* + CTLHN nếu đúng. E dùng diff array r vẫn tle
Hãy luôn nhớ cảm ơn và vote 5*
nếu câu trả lời hữu ích nhé!
`***` Giải thích:
`-` Gom các học sinh theo giá trị `\text(a[i])` `→` mỗi giá trị có danh sách vị trí xuất hiện
`-` Mỗi truy vấn không duyệt vị trí nữa, mà duyệt các số chia hết cho `x` `(x, 2x, 3x, …)`
`-` Với mỗi giá trị đó, lấy ra danh sách vị trí tương ứng
`-` Dùng tìm kiếm nhị phân để lọc các vị trí nằm trong đoạn `\text([l, r])`
`-` Chỉ cộng kẹo cho những vị trí thỏa điều kiện
`=>` Tổng thể: giảm từ duyệt N phần tử mỗi lần `→` chỉ duyệt các bội của `x` `+` vị trí liên quan `→` nhanh hơn nhiều
`***` Code:
#include <bits/stdc++.h>
using namespace std;
const int MAXA = 500000 + 5;
int main() {
// tăng thời gian chạy
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, Q;
cin >> N >> Q;
vector<int> a(N + 1);
for (int i = 1; i <= N; i++) cin >> a[i];
// lưu vị trí theo giá trị
vector<vector<int>> pos(MAXA);
for (int i = 1; i <= N; i++) {
pos[a[i]].push_back(i);
}
vector<long long> kq(N + 1, 0);
while (Q--) {
int l, r, x;
long long v;
cin >> l >> r >> x >> v;
// duyệt các bội của x
for (int a = x; a < MAXA; a += x) {
if (pos[a].empty()) continue;
auto &vec = pos[a];
// tìm đoạn trong [l, r]
auto it1 = lower_bound(vec.begin(), vec.end(), l);
auto it2 = upper_bound(vec.begin(), vec.end(), r);
for (auto it = it1; it != it2; ++it) {
kq[*it] += v;
}
}
}
for (int i = 1; i <= N; i++) {
cout << kq[i] << " ";
}
}
Hãy giúp mọi người biết câu trả lời này thế nào?
![]()
Bảng tin
0
89
0
lời giải vẫn bị tle a ạ =)) nma e cảm ơn, truy vấn cux là cách hay a ạ. link contest nếu a muốn test code: http s://hnoj.edu.vn/contest/tht2024_hn_ck_b_ c(bỏ dấu cách trước chữ s)
668
8077
617
gửi test ạ mik thử
0
89
0
http s://hnoj.edu.vn/contest/tht2024_hn_ck_b_c (bỏ dấu cách trước chữ s)
668
8077
617
t chịu á