let MXX = 10001;
let lazy =
new
Array(4 * MXX).fill(0);
let segment =
new
Array(4 * MXX).fill().map(() =>
new
Array(51).fill(0));
let ans =
new
Array(51).fill(0);
function
build(arr, low, high, ind, k) {
if
(low === high) {
let rem = arr[low] % k;
segment[ind][rem] = 1;
return
;
}
let mid = Math.floor((low + high) / 2);
build(arr, low, mid, 2 * ind + 1, k);
build(arr, mid + 1, high, 2 * ind + 2, k);
for
(let i = 0; i < k; i++) {
segment[ind][i] = segment[2 * ind + 1][i] + segment[2 * ind + 2][i];
}
}
function
update(l, r, low, high, ind, k, val) {
lazy[ind] %= k;
if
(lazy[ind] !== 0) {
if
(low !== high) {
lazy[2 * ind + 1] += lazy[ind];
lazy[2 * ind + 2] += lazy[ind];
lazy[2 * ind + 1] %= k;
lazy[2 * ind + 2] %= k;
}
let incr = lazy[ind];
let temp =
new
Array(k).fill(0);
for
(let i = 0; i < k; i++) {
temp[i] = segment[ind][i];
}
for
(let i = 0; i < k; i++) {
segment[ind][(incr + i) % k] = temp[i];
}
lazy[ind] = 0;
}
if
(high < low || low > r || high < l)
return
;
if
(low >= l && high <= r) {
val %= k;
let temp =
new
Array(k).fill(0);
for
(let i = 0; i < k; i++) {
temp[i] = segment[ind][i];
}
for
(let i = 0; i < k; i++) {
segment[ind][(val + i) % k] = temp[i];
}
if
(low !== high) {
lazy[2 * ind + 1] += val;
lazy[2 * ind + 2] += val;
lazy[2 * ind + 1] %= k;
lazy[2 * ind + 2] %= k;
}
return
;
}
let mid = Math.floor((low + high) / 2);
update(l, r, low, mid, 2 * ind + 1, k, val);
update(l, r, mid + 1, high, 2 * ind + 2, k, val);
for
(let i = 0; i < k; i++) {
segment[ind][i] = segment[2 * ind + 1][i] + segment[2 * ind + 2][i];
}
}
function
query(l, r, low, high, ind, k) {
lazy[ind] %= k;
if
(lazy[ind] !== 0) {
if
(low !== high) {
lazy[2 * ind + 1] += val;
lazy[2 * ind + 2] += val;
lazy[2 * ind + 1] %= k;
lazy[2 * ind + 2] %= k;
}
return
;
}
const mid = Math.floor((low + high) / 2);
update(l, r, low, mid, 2 * ind + 1, k, val);
update(l, r, mid + 1, high, 2 * ind + 2, k, val);
for
(let i = 0; i < k; i++) {
segment[ind][i] = segment[2 * ind + 1][i] + segment[2 * ind + 2][i];
}
}
function
query(l, r, low, high, ind, k) {
lazy[ind] %= k;
if
(lazy[ind] !== 0) {
if
(low !== high) {
lazy[2 * ind + 1] += lazy[ind];
lazy[2 * ind + 2] += lazy[ind];
lazy[2 * ind + 1] %= k;
lazy[2 * ind + 2] %= k;
}
const incr = lazy[ind];
const temp =
new
Array(k).fill(0);
for
(let i = 0; i < k; i++) {
temp[i] = segment[ind][i];
}
for
(let i = 0; i < k; i++) {
segment[ind][(incr + i) % k] = temp[i];
}
lazy[ind] = 0;
}
if
(high < low || low > r || high < l)
return
;
if
(low >= l && high <= r) {
for
(let i = 0; i < k; i++) {
ans[i] += segment[ind][i];
}
return
;
}
const mid = Math.floor((low + high) / 2);
query(l, r, low, mid, 2 * ind + 1, k);
query(l, r, mid + 1, high, 2 * ind + 2, k);
}
const arr = [7, 13, 5, 9, 16, 21];
const k = 4;
let q = 3;
let l = 3, r = 5;
build(arr, 0, arr.length - 1, 0, k);
query(l, r, 0, arr.length - 1, 0, k);
console.log(ans[0] +
" "
+ ans[1] +
" "
+ ans[2] +
" "
+ ans[3] +
"<br>"
);
for
(let i = 0; i < 51; i++) {
ans[i] = 0;
}
l = 0, r = 4;
let x = 1
update(l, r, 0, arr.length - 1, 0, k, x);
l = 2;
r = 5;
query(l, r, 0, arr.length - 1, 0, k);
console.log(ans[0] +
" "
+ ans[1] +
" "
+ ans[2] +
" "
+ ans[3]);