1 条题解
-
0
自动搬运
来自洛谷,原作者为

zuytong
且将新火试新茶,诗酒趁年华搬运于
2025-08-24 22:11:41,当前版本为作者最后更新于2022-09-07 09:35:19,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
思路
我们考虑开一棵线段树,表示区间 最后一次操作 2 的时间戳。
对于操作 1:我们交换树上 和 两点的值。
对于操作 2:我们进行区间 赋值。
对于操作 3:我们查询树上 点的值,并记录为 。
考虑将所有的询问离线下来,对 做扫描线:遇到操作 3 时,我们在 的位置加上 并更新前缀和;对于询问 ,我们查询 的后缀和,这个可以通过树状数组实现。
由于 同阶,时间复杂度为 。
代码
#include<iostream> #include<fstream> #include<algorithm> #include<cmath> #include<cstdlib> #include<cstring> #include<queue> #include<map> #include<set> #include<bitset> #define LL long long #define FOR(i, x, y) for(int i = (x); i <= (y); i++) #define ROF(i, x, y) for(int i = (x); i >= (y); i--) #define PFOR(i, x) for(int i = he[x]; i; i = r[i].nxt) inline int reads() { int sign = 1, re = 0; char c = getchar(); while(c < '0' || c > '9'){if(c == '-') sign = -1; c = getchar();} while('0' <= c && c <= '9'){re = re * 10 + (c - '0'); c = getchar();} return sign * re; } int n, m, q; int ty[1000005], x[1000005], y[1000005], val[1000005]; int tr[4000005]; #define ls (now << 1) #define rs ((now << 1) | 1) inline void down(int now) { if(tr[now]) { tr[ls] = tr[rs] = tr[now]; tr[now] = 0; } } void modify(int now, int l, int r, int L, int R, int ti) { if(L <= l && r <= R) return void(tr[now] = ti); down(now); int mid = (l + r) >> 1; if(L <= mid) modify(ls, l, mid, L, R, ti); if(mid < R) modify(rs, mid + 1, r, L, R, ti); } int query(int now, int l, int r, int to) { if(l == r) return tr[now]; if(tr[now]) return tr[now]; int mid = (l + r) >> 1; if(to <= mid) return query(ls, l, mid, to); else return query(rs, mid + 1, r, to); } LL sum[1000005]; inline int lb(int x) {return x & (-x);} inline void add(int x, int val) { if(!x) return; while(x <= m) sum[x] += val, x += lb(x); } inline LL get_sum(int x) { if(x < 1) return 0; LL re = 0; while(x) re += sum[x], x ^= lb(x); return re; } #define pii std::pair<int, int> #define mp std::make_pair std::vector<pii> qst[1000005]; LL ans[1000005]; signed main() { #ifndef ONLINE_JUDGE freopen("test.in", "r", stdin); freopen("test.out", "w", stdout); #endif n = reads(), m = reads(), q = reads(); FOR(i, 1, m) { ty[i] = reads(); if(ty[i] == 1) { x[i] = reads(), y[i] = reads(); int vx = query(1, 1, n, x[i]), vy = query(1, 1, n, y[i]); modify(1, 1, n, x[i], x[i], vy), modify(1, 1, n, y[i], y[i], vx); } else if(ty[i] == 2) { x[i] = reads(), y[i] = reads(), val[i] = reads(); modify(1, 1, n, x[i], y[i], i); } else { x[i] = reads(); y[i] = query(1, 1, n, x[i]); } } FOR(i, 1, q) { int l = reads(), r = reads(); qst[r].emplace_back(mp(l, i)); } FOR(i, 1, m) { if(ty[i] == 3) add(y[i], val[y[i]]); for(pii j : qst[i]) ans[j.second] = get_sum(i) - get_sum(j.first - 1); } FOR(i, 1, q) printf("%lld\n", ans[i]); return 0; }
- 1
信息
- ID
- 8028
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者