第一眼看到这个题目以为是平衡树类的题,但是这样内存不太行(很大可能是我没做多少平衡树的题
我们把m个数组拉成一个数组,赋予连续的编号,区间赋值相当于就是线段树上区间赋一个等差数列。
我们询问的时候可以单点查询这个位置具体是哪个数组的哪个元素。由于m个数组存在的区间更新问题。所以我们可以更新线段树的时候加上一个时间戳。把更新操作加上时间戳全都提出来,询问操作也提出时间戳存下来。
问题就转变成了一个区间加法 加单点查询的问题了。。。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 3;
#define fi first
#define se second
int n, m, q;
int a[N];
int s[N], b[N];
vector<int>t[N];
void add(int x, int y, vector<int>&t, int s) {
for (; x <= s; x += x & -x)t[x] += y;
}
int get(int x, vector<int>&t) {
int y = 0;
for (; x; x -= x & -x)y += t[x];
return y;
}
#define mid (l+r>>1)
#define ls o<<1
#define rs o<<1|1
int T[N << 2];
int tim[N << 2];
// 先清0 再加
//一个区间 只有一个等差
void push_down(int o, int l, int r) {
if (T[o]) {
T[ls] = T[o];
T[rs] = T[o] + (mid + 1 - l);
tim[ls] = tim[rs] = tim[o];
T[o]=0;
}
}
int cnt[N];
void up(int o, int l, int r, int x, int y, int z, int ti) {
if (l >= x && r <= y) {
T[o] = z + (l - x);
tim[o] = ti;
return ;
}
push_down(o, l, r);
if (x <= mid)up(ls, l, mid, x, y, z, ti);
if (y > mid)up(rs, mid + 1, r, x, y, z, ti);
}
pair<int, int> get(int o, int l, int r, int x) {
if (l == r) {
return {T[o], tim[o]};
}
push_down(o, l, r);
if (x <= mid)return get(ls, l, mid, x);
else return get(rs, mid + 1, r, x);
}
int find(int x) {
int l = 1, r = m, ok = -1;
while (l <= r) {
if (b[mid] >= x)ok = mid, r = mid - 1;
else l = mid + 1;
}
assert(ok!=-1);
return ok;
}
struct uzi {
int pos, l, r, i;
bool operator < (const uzi & t)const {
return pos < t.pos;
}
} P[N], qu[N];
int dd, vis[N], tt;
int main() {
ios::sync_with_stdio(false);
cin >> n >> m >> q;
for (int i = 1; i <= m; i++) {
cin >> s[i];
b[i] = b[i - 1] + s[i];
t[i].resize(s[i] + 1);
for (int j = 1; j <= s[i]; j++) {
int z; cin >> z;
add(j, z, t[i], s[i]);
add(j + 1, -z, t[i], s[i]);
}
}
for (int i = 1; i <= q; i++) {
int op, x, l, r, p;
cin >> op;
if (op == 1) {
cin >> x >> p;
int pre = b[x - 1];
up(1, 1, n, p, p + s[x] - 1, pre + 1, i);
} else if (op == 2) {
vis[i] = 1;
cin >> p;
auto index = get(1, 1, n, p);
if (!index.first) {
qu[++tt] = { -1, 0, 0, i};
continue;
}
int last = find(index.fi);
qu[++tt] = {index.se, last, index.fi - b[last - 1], i};
} else {
cin >> x >> l >> r;
P[++dd] = {i, l, r, x};
}
}
sort(P + 1, P + 1 + dd);
sort(qu + 1, qu + 1 + tt);
int l = 0;
vector<int>ans(q + 1);
for (int i = 1; i <= tt; i++) {
while (l + 1 <= dd && P[l + 1].pos <= qu[i].pos) {
l++;
add(P[l].l, 1, t[P[l].i], s[P[l].i]);
add(P[l].r + 1, -1, t[P[l].i], s[P[l].i]);
}
if (qu[i].pos == -1) {
ans[qu[i].i] = 0;
} else ans[qu[i].i] = get(qu[i].r, t[qu[i].l]);
}
for (int i = 1; i <= q; i++) {
if (vis[i])cout << ans[i] % 256 << '\n';
}
return 0;
}