RE70 求助

P3302 [SDOI2013] 森林

https://www.luogu.org/record/show?rid=16026345
by iodwad @ 2019-02-02 19:49:24


emmm 把主席树动态开点删掉就过了。。。 并不清楚是为什么 请问各位 下面是改过的代码(删去动态开点) ```cpp #include <iostream> #include <cstdio> #include <algorithm> #include <vector> const int MAXN = 8e4; int n, m, t, tot, lg; int a[MAXN | 1], p[MAXN | 1], father[24][MAXN | 1], depth[MAXN | 1], fset[MAXN | 1], size[MAXN | 1]; std::vector < int > e[MAXN | 1]; inline int read() { register int x = 0; register char ch = getchar(); while(!isdigit(ch)) ch = getchar(); while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); } return x; } int find(int x) { return fset[x] == x ? x : fset[x] = find(fset[x]); } void merge(int x, int y) { x = find(x); y = find(y); size[y] += size[x]; fset[x] = y; } namespace persistentSegmentTree { struct Node { int sumv; Node *ch[2]; Node() : sumv(0) { ch[0] = ch[1] = NULL; } } *root[MAXN | 1]; inline int sumv(Node *o) { return o == NULL ? 0 : o -> sumv; } inline void pushup(Node *o) { o -> sumv = sumv(o -> ch[0]) + sumv(o -> ch[1]); } /* void insert(Node *lst, Node *&now, int l, int r, int pos) { if(now == NULL) now = new Node; if(l == r) { now -> sumv = sumv(lst) + 1; return; } int mid = (l + r) >> 1; if(lst != NULL) { if(pos <= mid) { now -> ch[1] = lst -> ch[1]; insert(lst -> ch[0], now -> ch[0], l, mid, pos); } else { now -> ch[0] = lst -> ch[0]; insert(lst -> ch[1], now -> ch[1], mid + 1, r, pos); } } else { if(pos <= mid) insert(NULL, now -> ch[0], l, mid, pos); else insert(NULL, now -> ch[1], mid + 1, r, pos); } pushup(now); } int query(Node *x, Node *y, Node *lca, Node *fa, int l, int r, int k) { if(l == r) return l; int delta = sumv(x ? x -> ch[0] : x) + sumv(y ? y -> ch[0] : y) - sumv(lca ? lca -> ch[0] : lca) - sumv(fa ? fa -> ch[0] : fa); int mid = (l + r) >> 1; if(delta >= k) return query(x ? x -> ch[0] : x, y ? y -> ch[0] : y, lca ? lca -> ch[0] : lca, fa ? fa -> ch[0] : fa, l, mid, k); return query(x ? x -> ch[1] : x, y ? y -> ch[1] : y, lca ? lca -> ch[1] : lca, fa ? fa -> ch[1] : fa, mid + 1, r, k - delta); } */ void build(Node *&now, int l, int r) { now = new Node; if(l == r) return; int mid = (l + r) >> 1; build(now -> ch[0], l, mid); build(now -> ch[1], mid + 1, r); } void insert(Node *lst, Node *&now, int l, int r, int pos) { if(now == NULL) now = new Node; if(l == r) { now -> sumv = lst -> sumv + 1; return; } int mid = (l + r) >> 1; if(pos <= mid) { now -> ch[1] = lst -> ch[1]; insert(lst -> ch[0], now -> ch[0], l, mid, pos); } else { now -> ch[0] = lst -> ch[0]; insert(lst -> ch[1], now -> ch[1], mid + 1, r, pos); } pushup(now); } int query(Node *x, Node *y, Node *lca, Node *fa, int l, int r, int k) { if(l == r) return l; int delta = x -> ch[0] -> sumv + y -> ch[0] -> sumv - lca -> ch[0] -> sumv - fa -> ch[0] -> sumv; int mid = (l + r) >> 1; if(delta >= k) return query(x -> ch[0], y -> ch[0], lca -> ch[0], fa -> ch[0], l, mid, k); return query(x -> ch[1], y -> ch[1], lca -> ch[1], fa -> ch[1], mid + 1, r, k - delta); } } using namespace persistentSegmentTree; void dfs(int x, int fa) { father[0][x] = fa; depth[x] = depth[fa] + 1; insert(root[fa], root[x], 1, tot, a[x]); if(fa) merge(x, fa); for(int i = 1; i <= lg; ++i) father[i][x] = father[i - 1][father[i - 1][x]]; for(std::vector < int >::iterator it = e[x].begin(); it != e[x].end(); ++it) { int to = *it; if(to == fa) continue; dfs(to, x); } } int LCA(int x, int y) { if(depth[x] < depth[y]) std::swap(x, y); for(int i = lg; ~i; --i) if(father[i][x] && depth[father[i][x]] >= depth[y]) x = father[i][x]; if(x == y) return x; for(int i = lg; ~i; --i) { if(father[i][x] && father[i][y] && father[i][x] != father[i][y]) { x = father[i][x]; y = father[i][y]; } } return father[0][x]; } int ask(int x, int y, int z) { int lca = LCA(x, y); return query(root[x], root[y], root[lca], root[father[0][lca]], 1, tot, z); } void dfsMerge(int x, int fa) { father[0][x] = fa; depth[x] = depth[fa] + 1; insert(root[fa], root[x], 1, tot, a[x]); for(int i = 1; i <= lg; ++i) father[i][x] = father[i - 1][father[i - 1][x]]; for(std::vector < int >::iterator it = e[x].begin(); it != e[x].end(); ++it) { int to = *it; if(to != fa) dfsMerge(to, x); } } void doit(int x, int y) { int fx = find(x), fy = find(y); if(size[fx] > size[fy]) { std::swap(x, y); } e[x].push_back(y); e[y].push_back(x); merge(x, y); dfsMerge(x, y); } int main() { // freopen("in.in", "r", stdin); // freopen("out.out", "w", stdout); read(); n = read(); m = read(); t = read(); for(int i = 0, l = 1; ; ++i, l <<= 1) { if(l > n) { lg = i - 1; break; } } for(int i = 1; i <= n; ++i) { a[i] = p[i] = read(); fset[i] = i; size[i] = 1; } std::sort(p + 1, p + 1 + n); tot = std::unique(p + 1, p + 1 + n) - p - 1; for(int i = 1; i <= n; ++i) a[i] = std::lower_bound(p + 1, p + 1 + tot, a[i]) - p; // for(int i = 1; i <= n; ++i) printf("%d ", a[i]); for(int i = 1; i <= m; ++i) { int u = read(), v = read(); e[u].push_back(v); e[v].push_back(u); } build(root[0], 1, tot); for(int i = 1; i <= n; ++i) if(!depth[i]) dfs(i, 0); int lastans = 0; while(t--) { char opt; std::cin >> opt; if(opt == 'Q') { int x = read() ^ lastans, y = read() ^ lastans, z = read() ^ lastans; lastans = p[ask(x, y, z)]; printf("%d\n", lastans); } else { int x = read() ^ lastans, y = read() ^ lastans; doit(x, y); } } return 0; } ```
by iodwad @ 2019-02-02 20:08:17


找到问题了。。。是因为动态开点没有删去以前的信息 已经 AC
by iodwad @ 2019-02-02 20:27:31


|