#include <bits/stdc++.h>
#define int long long
using namespace std;
void io()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
}
int c2(int n) { return (n * (n - 1) / 2); } /* nC2 */
int c3(int n) { return (n * (n - 1) * (n - 2)) / 6; }; /* nC3*/
int k;
struct node
{
vector<int> freq;
node()
{
freq.resize(k, 0);
}
node(int val)
{
freq.resize(k, 0);
freq[(val % k + k) % k] = 1;
}
};
struct segtree
{
vector<node> tree; /*each node holds freq of size k */
int size = 1;
void init(int n)
{
while (size < n)
size <<= 1;
tree.resize(2 * size);
for (int i = 0; i < 2 * size; i++)
{
tree[i] = node();
}
}
node combine(node &a, node &b) /* O(K) combine the freq */
{
node res;
for (int i = 0; i < k; i++)
{
res.freq[i] = a.freq[i] + b.freq[i];
}
return res;
}
void build(vector<int> &a, int x, int lx, int rx) /* O(n*k) */
{
if (rx - lx == 1)
{
if (lx < a.size())
tree[x] = node(a[lx]);
return;
}
int m = (rx + lx) >> 1;
build(a, 2 * x + 1, lx, m);
build(a, 2 * x + 2, m, rx);
tree[x] = combine(tree[2 * x + 1], tree[2 * x + 2]);
}
void build(vector<int> &a)
{
build(a, 0, 0, size);
}
void update(int i, int v, int x, int lx, int rx) /* O(log(n) * k) */
{
if (rx - lx == 1)
{
tree[x] = node(v);
return;
}
int m = (rx + lx) >> 1;
if (i < m)
update(i, v, 2 * x + 1, lx, m);
else
update(i, v, 2 * x + 2, m, rx);
tree[x] = combine(tree[2 * x + 1], tree[2 * x + 2]);
}
void update(int i, int v)
{
update(i, v, 0, 0, size);
}
node query(int l, int r, int x, int lx, int rx) /* O(log(n) * k) */
{
if (lx >= r || rx <= l)
return node();
if (lx >= l && rx <= r)
return tree[x];
int m = (rx + lx) >> 1;
node left = query(l, r, 2 * x + 1, lx, m), right = query(l, r, 2 * x + 2, m, rx);
return combine(left, right);
}
node query(int l, int r)
{
return query(l, r, 0, 0, size);
}
};
int cnttriples(vector<int> &freq) // O(k^2)
{
int res = 0;
for (int i = 0; i < k; i++)
{
for (int j = i; j < k; j++)
{
int m = (k - (i + j) % k) % k;
if (m < j)
continue; // avoid duplicates
if (i == j && j == m)
{
// all in
res += c3(freq[i]);
}
else if (i == j)
{
// two equal one unique
res += c2(freq[i]) * freq[m];
}
else if (j == m)
{
// two equal one unique
res += freq[i] * c2(freq[j]);
}
else
{
// all out
res += freq[i] * freq[j] * freq[m];
}
}
}
return res;
}
signed main()
{
io();
int n;
cin >> n >> k;
vector<int> a(n);
for (auto &i : a)
cin >> i;
segtree st; /* the segment is zero based exclusive right bound */
st.init(n);
st.build(a);
int q;
cin >> q;
while (q--) // for type one O(log n * k ) / for type 2 O(k ^ 2 + log n * k )
// Worst case: O(q * max(log n * k, k^2))
{
int type;
cin >> type;
if (type == 1)
{
int i, v;
cin >> i >> v;
i--;
st.update(i, v);
}
else
{
int l, r;
cin >> l >> r;
l--;
node res = st.query(l, r);
cout << cnttriples(res.freq) << '\n';
}
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNkZWZpbmUgaW50IGxvbmcgbG9uZwp1c2luZyBuYW1lc3BhY2Ugc3RkOwp2b2lkIGlvKCkKewojaWZuZGVmIE9OTElORV9KVURHRQogIGZyZW9wZW4oImlucHV0LnR4dCIsICJyIiwgc3RkaW4pOwojZW5kaWYKfQppbnQgYzIoaW50IG4pIHsgcmV0dXJuIChuICogKG4gLSAxKSAvIDIpOyB9ICAgICAgICAgICAgLyogbkMyICovCmludCBjMyhpbnQgbikgeyByZXR1cm4gKG4gKiAobiAtIDEpICogKG4gLSAyKSkgLyA2OyB9OyAvKiBuQzMqLwoKaW50IGs7CnN0cnVjdCBub2RlCnsKICB2ZWN0b3I8aW50PiBmcmVxOwogIG5vZGUoKQogIHsKICAgIGZyZXEucmVzaXplKGssIDApOwogIH0KICBub2RlKGludCB2YWwpCiAgewogICAgZnJlcS5yZXNpemUoaywgMCk7CiAgICBmcmVxWyh2YWwgJSBrICsgaykgJSBrXSA9IDE7CiAgfQp9OwpzdHJ1Y3Qgc2VndHJlZQp7CiAgdmVjdG9yPG5vZGU+IHRyZWU7IC8qZWFjaCBub2RlIGhvbGRzIGZyZXEgb2Ygc2l6ZSBrICovCiAgaW50IHNpemUgPSAxOwogIHZvaWQgaW5pdChpbnQgbikKICB7CiAgICB3aGlsZSAoc2l6ZSA8IG4pCiAgICAgIHNpemUgPDw9IDE7CiAgICB0cmVlLnJlc2l6ZSgyICogc2l6ZSk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IDIgKiBzaXplOyBpKyspCiAgICB7CiAgICAgIHRyZWVbaV0gPSBub2RlKCk7CiAgICB9CiAgfQogIG5vZGUgY29tYmluZShub2RlICZhLCBub2RlICZiKSAvKiBPKEspIGNvbWJpbmUgdGhlIGZyZXEgKi8KICB7CiAgICBub2RlIHJlczsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgazsgaSsrKQogICAgewogICAgICByZXMuZnJlcVtpXSA9IGEuZnJlcVtpXSArIGIuZnJlcVtpXTsKICAgIH0KICAgIHJldHVybiByZXM7CiAgfQogIHZvaWQgYnVpbGQodmVjdG9yPGludD4gJmEsIGludCB4LCBpbnQgbHgsIGludCByeCkgLyogTyhuKmspICovCiAgewogICAgaWYgKHJ4IC0gbHggPT0gMSkKICAgIHsKICAgICAgaWYgKGx4IDwgYS5zaXplKCkpCiAgICAgICAgdHJlZVt4XSA9IG5vZGUoYVtseF0pOwogICAgICByZXR1cm47CiAgICB9CiAgICBpbnQgbSA9IChyeCArIGx4KSA+PiAxOwogICAgYnVpbGQoYSwgMiAqIHggKyAxLCBseCwgbSk7CiAgICBidWlsZChhLCAyICogeCArIDIsIG0sIHJ4KTsKICAgIHRyZWVbeF0gPSBjb21iaW5lKHRyZWVbMiAqIHggKyAxXSwgdHJlZVsyICogeCArIDJdKTsKICB9CiAgdm9pZCBidWlsZCh2ZWN0b3I8aW50PiAmYSkKICB7CiAgICBidWlsZChhLCAwLCAwLCBzaXplKTsKICB9CiAgdm9pZCB1cGRhdGUoaW50IGksIGludCB2LCBpbnQgeCwgaW50IGx4LCBpbnQgcngpIC8qIE8obG9nKG4pICogaykgKi8KICB7CiAgICBpZiAocnggLSBseCA9PSAxKQogICAgewogICAgICB0cmVlW3hdID0gbm9kZSh2KTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaW50IG0gPSAocnggKyBseCkgPj4gMTsKICAgIGlmIChpIDwgbSkKICAgICAgdXBkYXRlKGksIHYsIDIgKiB4ICsgMSwgbHgsIG0pOwogICAgZWxzZQogICAgICB1cGRhdGUoaSwgdiwgMiAqIHggKyAyLCBtLCByeCk7CiAgICB0cmVlW3hdID0gY29tYmluZSh0cmVlWzIgKiB4ICsgMV0sIHRyZWVbMiAqIHggKyAyXSk7CiAgfQogIHZvaWQgdXBkYXRlKGludCBpLCBpbnQgdikKICB7CiAgICB1cGRhdGUoaSwgdiwgMCwgMCwgc2l6ZSk7CiAgfQogIG5vZGUgcXVlcnkoaW50IGwsIGludCByLCBpbnQgeCwgaW50IGx4LCBpbnQgcngpIC8qIE8obG9nKG4pICogaykgKi8KICB7CiAgICBpZiAobHggPj0gciB8fCByeCA8PSBsKQogICAgICByZXR1cm4gbm9kZSgpOwogICAgaWYgKGx4ID49IGwgJiYgcnggPD0gcikKICAgICAgcmV0dXJuIHRyZWVbeF07CiAgICBpbnQgbSA9IChyeCArIGx4KSA+PiAxOwogICAgbm9kZSBsZWZ0ID0gcXVlcnkobCwgciwgMiAqIHggKyAxLCBseCwgbSksIHJpZ2h0ID0gcXVlcnkobCwgciwgMiAqIHggKyAyLCBtLCByeCk7CiAgICByZXR1cm4gY29tYmluZShsZWZ0LCByaWdodCk7CiAgfQogIG5vZGUgcXVlcnkoaW50IGwsIGludCByKQogIHsKICAgIHJldHVybiBxdWVyeShsLCByLCAwLCAwLCBzaXplKTsKICB9Cn07CmludCBjbnR0cmlwbGVzKHZlY3RvcjxpbnQ+ICZmcmVxKSAvLyBPKGteMikKewogIGludCByZXMgPSAwOwogIGZvciAoaW50IGkgPSAwOyBpIDwgazsgaSsrKQogIHsKICAgIGZvciAoaW50IGogPSBpOyBqIDwgazsgaisrKQogICAgewogICAgICBpbnQgbSA9IChrIC0gKGkgKyBqKSAlIGspICUgazsKICAgICAgaWYgKG0gPCBqKQogICAgICAgIGNvbnRpbnVlOyAvLyBhdm9pZCBkdXBsaWNhdGVzCgogICAgICBpZiAoaSA9PSBqICYmIGogPT0gbSkKICAgICAgewogICAgICAgIC8vIGFsbCBpbgogICAgICAgIHJlcyArPSBjMyhmcmVxW2ldKTsKICAgICAgfQogICAgICBlbHNlIGlmIChpID09IGopCiAgICAgIHsKICAgICAgICAvLyB0d28gZXF1YWwgb25lIHVuaXF1ZQogICAgICAgIHJlcyArPSBjMihmcmVxW2ldKSAqIGZyZXFbbV07CiAgICAgIH0KICAgICAgZWxzZSBpZiAoaiA9PSBtKQogICAgICB7CiAgICAgICAgLy8gdHdvIGVxdWFsIG9uZSB1bmlxdWUKICAgICAgICByZXMgKz0gZnJlcVtpXSAqIGMyKGZyZXFbal0pOwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIC8vIGFsbCBvdXQKICAgICAgICByZXMgKz0gZnJlcVtpXSAqIGZyZXFbal0gKiBmcmVxW21dOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiByZXM7Cn0KCnNpZ25lZCBtYWluKCkKewogIGlvKCk7CiAgaW50IG47CiAgY2luID4+IG4gPj4gazsKICB2ZWN0b3I8aW50PiBhKG4pOwogIGZvciAoYXV0byAmaSA6IGEpCiAgICBjaW4gPj4gaTsKICBzZWd0cmVlIHN0OyAvKiB0aGUgc2VnbWVudCBpcyB6ZXJvIGJhc2VkIGV4Y2x1c2l2ZSByaWdodCBib3VuZCAqLwogIHN0LmluaXQobik7CiAgc3QuYnVpbGQoYSk7CiAgaW50IHE7CiAgY2luID4+IHE7CgogIHdoaWxlIChxLS0pIC8vIGZvciB0eXBlIG9uZSBPKGxvZyBuICogayApIC8gZm9yIHR5cGUgMiBPKGsgXiAyICArIGxvZyBuICogayApCiAgLy8gV29yc3QgY2FzZTogTyhxICogbWF4KGxvZyBuICogaywga14yKSkKICB7CiAgICBpbnQgdHlwZTsKICAgIGNpbiA+PiB0eXBlOwogICAgaWYgKHR5cGUgPT0gMSkKICAgIHsKICAgICAgaW50IGksIHY7CiAgICAgIGNpbiA+PiBpID4+IHY7CiAgICAgIGktLTsKICAgICAgc3QudXBkYXRlKGksIHYpOwogICAgfQogICAgZWxzZQogICAgewogICAgICBpbnQgbCwgcjsKICAgICAgY2luID4+IGwgPj4gcjsKICAgICAgbC0tOwogICAgICBub2RlIHJlcyA9IHN0LnF1ZXJ5KGwsIHIpOwogICAgICBjb3V0IDw8IGNudHRyaXBsZXMocmVzLmZyZXEpIDw8ICdcbic7CiAgICB9CiAgfQogIHJldHVybiAwOwp9