【BZOJ2333】【SCOI2011】棘手的操作
2018-03-19 14:03
471 查看
【题目链接】
点击打开链接
【思路要点】
补档博客,无题解。
【代码】
点击打开链接
【思路要点】
补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 300005 #define INF 1e9 struct Node { int lc, rc; int maxnum, tag; }; Node a[MAXN * 2]; int n, q, timer, size, dfn[MAXN], home[MAXN]; int f[MAXN], value[MAXN], rit[MAXN]; int x[MAXN], y[MAXN], z[MAXN]; char opt[MAXN][3]; vector <int> t[MAXN]; int F(int x) { if (f[x] == x) return x; else return f[x] = F(f[x]); } void dfs(int pos) { dfn[pos] = ++timer; for (unsigned i = 0; i < t[pos].size(); i++) dfs(t[pos][i]); } void update(int x) { a[x].maxnum = max(a[a[x].lc].maxnum, a[a[x].rc].maxnum); } void pushdown(int x) { a[a[x].lc].tag += a[x].tag; a[a[x].lc].maxnum += a[x].tag; a[a[x].rc].tag += a[x].tag; a[a[x].rc].maxnum += a[x].tag; a[x].tag = 0; } void build(int pos, int l, int r) { if (l == r) { a[pos].maxnum = value[home[l]]; return; } int mid = (l + r) / 2; a[pos].lc = ++size; build(size, l, mid); a[pos].rc = ++size; build(size, mid + 1, r); update(pos); } void maintain(int pos, int l, int r, int ql, int qr, int v) { if (l == ql && r == qr) { a[pos].tag += v; a[pos].maxnum += v; return; } int mid = (l + r) / 2; pushdown(pos); if (mid >= ql) maintain(a[pos].lc, l, mid, ql, min(mid, qr), v); if (mid + 1 <= qr) maintain(a[pos].rc, mid + 1, r, max(mid + 1, ql), qr, v); update(pos); } int query(int pos, int l, int r, int ql, int qr) { if (l == ql && r == qr) return a[pos].maxnum; int mid = (l + r) / 2, ans = -INF; pushdown(pos); if (mid >= ql) ans = max(ans, query(a[pos].lc, l, mid, ql, min(mid, qr))); if (mid + 1 <= qr) ans = max(ans, query(a[pos].rc, mid + 1, r, max(mid + 1, ql), qr)); return ans; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &value[i]); f[i] = i; rit[i] = i; } scanf("%d", &q); for (int i = 1; i <= q; i++) { scanf("%s", opt[i]); if (opt[i][0] == 'U') { scanf("%d%d", &x[i], &y[i]); int tx = F(x[i]), ty = F(y[i]); if (tx == ty) continue; f[ty] = tx; rit[tx] = rit[ty]; t[tx].push_back(ty); } if (opt[i][0] == 'A') { if (opt[i][1] == '1') scanf("%d%d", &x[i], &y[i]); if (opt[i][1] == '2') { scanf("%d%d", &x[i], &y[i]); x[i] = F(x[i]); z[i] = rit[x[i]]; } if (opt[i][1] == '3') scanf("%d", &y[i]); } if (opt[i][0] == 'F') { if (opt[i][1] == '1') scanf("%d", &x[i]); if (opt[i][1] == '2') { scanf("%d", &x[i]); x[i] = F(x[i]); z[i] = rit[x[i]]; } } } for (int i = 1; i <= n; i++) if (f[i] == i) dfs(i); for (int i = 1; i <= n; i++) home[dfn[i]] = i; build(0, 1, n); for (int i = 1; i <= q; i++) { if (opt[i][0] == 'A') { if (opt[i][1] == '1') maintain(0, 1, n, dfn[x[i]], dfn[x[i]], y[i]); if (opt[i][1] == '2') maintain(0, 1, n, dfn[x[i]], dfn[z[i]], y[i]); if (opt[i][1] == '3') maintain(0, 1, n, 1, n, y[i]); } if (opt[i][0] == 'F') { if (opt[i][1] == '1') printf("%d\n", query(0, 1, n, dfn[x[i]], dfn[x[i]])); if (opt[i][1] == '2') printf("%d\n", query(0, 1, n, dfn[x[i]], dfn[z[i]])); if (opt[i][1] == '3') printf("%d\n", query(0, 1, n, 1, n)); } } return 0; }
相关文章推荐
- 【bzoj2333】 SCOI2011—棘手的操作
- 【左偏树】【bzoj 2333】: [SCOI2011]棘手的操作
- BZOJ 2333 SCOI2011 棘手的操作 可并堆套可并堆
- [BZOJ2333][SCOI2011]棘手的操作(可并堆||线段树)
- 【BZOJ2333】【SCOI2011】棘手的操作 可并堆+堆套堆(什么嘛,用个set就好啦)
- [bzoj2333][SCOI2011][棘手的操作]
- 【BZOJ2333】【SCOI2011】棘手的操作 treap合并
- bzoj 2333: [SCOI2011]棘手的操作 离线+线段树
- bzoj 2333: [SCOI2011]棘手的操作(线段树+离线操作)
- 【BZOJ】2333: [SCOI2011]棘手的操作
- 【BZOJ2333】棘手的操作(SCOI2011)-线段树+并查集+离线处理
- [BZOJ2333][SCOI2011][可并堆]棘手的操作
- (右偏树)Bzoj2333: [SCOI2011]棘手的操作
- BZOJ 2333 [SCOI2011]棘手的操作
- BZOJ 2333 SCOI2011 棘手的操作 并查集+可并堆
- (右偏树)Bzoj2333: [SCOI2011]棘手的操作
- 【bzoj2333】 [SCOI2011]棘手的操作 可并堆+lazy标记
- [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
- 【bzoj2333】[SCOI2011]棘手的操作 可并堆+set
- BZOJ 2333 SCOI 2011 棘手的操作 可并堆