BZOJ3720 Gty的妹子树

来源:互联网 发布:论文盒子软件好用吗 编辑:程序博客网 时间:2024/05/01 19:36

[Solution]

It is likely that you need to modify the dfs order by a dynamic data structure. However, n is not big enough to use log-level algorithm. Divide the tree into sqrt(n) parts. Then use treaps to modify each part.


[Code]

So ugly and slow.


#include <cstdio>#include <cctype>#include <cstdlib>#include <algorithm>using namespace std;struct edge {int t;edge *next;};template <class _INT>void readInt(_INT& s) {int d;bool nag = 0;s = 0;while (!isdigit(d = getchar()))if (d == '-')nag = 1;while ((s = s * 10 + d - 48), isdigit(d = getchar()));if (nag)s = -s;}const int maxn = 60009;int n, m, lans, fa[maxn], w[maxn], d[maxn];int pcsz, tp, fp[maxn], pd0[maxn], prt[maxn], pfa[maxn];edge *ht[maxn], *hp[maxn], *ep, elst[maxn * 6];namespace treap {//{{{int tn, ls[maxn], rs[maxn], vl[maxn], w[maxn], sz[maxn];inline void init() {tn = 0;sz[0] = 0;}inline int newNode(int v) {++ tn;ls[tn] = 0;rs[tn] = 0;vl[tn] = v;sz[tn] = 1;w[tn] = rand();return tn;}inline void lRot(int& p) {int q = rs[p];rs[p] = ls[q];ls[q] = p;sz[q] = sz[p];sz[p] = sz[ls[p]] + sz[rs[p]] + 1;p = q;}inline void rRot(int& p) {int q = ls[p];ls[p] = rs[q];rs[q] = p;sz[q] = sz[p];sz[p] = sz[ls[p]] + sz[rs[p]] + 1;p = q;}inline void maintain(int& p, bool d) {if (d) {if (w[ls[p]] > w[p])rRot(p);}elseif (w[rs[p]] > w[p])lRot(p);}void ins(int& p, int v) {if (!p)p = newNode(v);else {if (v < vl[p])ins(ls[p], v);elseins(rs[p], v);++ sz[p];maintain(p, v < vl[p]);}}bool ers(int& p, int v) {if (!p)return 0;else if (vl[p] == v) {if (!ls[p])p = rs[p];else if (!rs[p])p = ls[p];else {int q = ls[p];while (rs[q])q = rs[q];vl[p] = vl[q];-- sz[p];return ers(ls[p], vl[p]);}return 1;}else {-- sz[p];if (v < vl[p])return ers(ls[p], v);elsereturn ers(rs[p], v);}}int cntUpper(int p, int v) {if (!p)return 0;else if (vl[p] > v)return sz[rs[p]] + 1 + cntUpper(ls[p], v);elsereturn cntUpper(rs[p], v);}};//}}}inline void addEdge(edge** head, int u, int v) {ep-> t = v;ep-> next = head[u];head[u] = ep ++;}void buildTree() {static int q[maxn];int hd = 0, tl = 1;for (int i = 0; i < maxn; ++ i)fa[i] = -1;q[hd] = 1;fa[1] = 0;d[1] = 1;fp[0] = 0;tp = 0;while (hd < tl) {int p = q[hd ++];if (fa[p] && d[p] - pd0[fp[fa[p]]] < pcsz) {fp[p] = fp[fa[p]];treap :: ins(prt[fp[p]], w[p]);}else {fp[p] = ++ tp;treap :: ins(prt[fp[p]], w[p]);pd0[fp[p]] = d[p];pfa[fp[p]] = fp[fa[p]];addEdge(hp, fp[fa[p]], fp[p]);}for (edge* e = ht[p]; e; e = e-> next)if (fa[e-> t] == -1) {fa[e-> t] = p;d[e-> t] = d[p] + 1;q[tl ++] = e-> t;}}}int query(int p, int v) {static int q[maxn], qp[maxn];int hd = 0, tl = 1, tq = 0, s = 0, p0 = fp[p];q[hd] = p;while (hd < tl) {int p = q[hd ++];if (w[p] > v)s ++;for (edge* e = ht[p]; e; e = e-> next)if (fa[e-> t] == p) {if (fp[e-> t] == fp[p])q[tl ++] = e-> t;elseqp[tq ++] = fp[e-> t];}}hd = 0, tl = tq;while (hd < tl) {int p = qp[hd ++];if (p != p0)s += treap :: cntUpper(prt[p], v);for (edge* e = hp[p]; e; e = e-> next)if (pfa[e-> t] == p)qp[tl ++] = e-> t;}return s;}int main() {srand(45239423);treap :: init();for (int i = 0; i < maxn; ++ i)prt[i] = 0;ep = elst;readInt(n);for (pcsz = 0; pcsz * pcsz < n * 2; ++ pcsz);lans = 0;for (int i = 0; i < n - 1; i ++) {int u, v;readInt(u);readInt(v);addEdge(ht, u, v);addEdge(ht, v, u);}for (int i = 1; i <= n; i ++)readInt(w[i]);buildTree();readInt(m);while (m --) {int opt, u, x;readInt(opt);readInt(u);readInt(x);u ^= lans;x ^= lans;if (u > n) {for (int i = 0; i < m; ++ i)puts("WAAAAAAAAAA");return 12345;}if (opt == 0)printf("%d\n", (lans = query(u, x)));else if (opt == 1) {treap :: ers(prt[fp[u]], w[u]);w[u] = x;treap :: ins(prt[fp[u]], w[u]);}else if (opt == 2) {n ++;addEdge(ht, u, n);fa[n] = u;w[n] = x;int p = n;d[p] = d[fa[p]] + 1;if (d[p] - pd0[fp[fa[p]]] < pcsz) {fp[p] = fp[fa[p]];treap :: ins(prt[fp[p]], w[p]);}else {fp[p] = ++ tp;treap :: ins(prt[fp[p]], w[p]);pd0[fp[p]] = d[p];pfa[fp[p]] = fp[fa[p]];addEdge(hp, fp[fa[p]], fp[p]);}}lans = 0;}}


0 0
原创粉丝点击