二次联通门 : BZOJ 3435: [Wc2014]紫荆花之恋
二次联通门 : luogu P3920 [WC2014]紫荆花之恋
/* luogu P3920 [WC2014]紫荆花之恋 怀疑人生 */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #define rg register #define INF 1e9 #define EPS 0.78 #define Max 100050 typedef long long LL; int c[Max * 2][3], h[Max], d[Max], r[Max], li[Max], N, M, EC = 1; LL Answer; int dis[Max][30], fi[Max], Dis[Max], Zero; bool Flag; const int BUF = 123123123; char Buf[BUF], *buf = Buf; inline void read (int &n) { rg char c = getchar (); for (n = 0; !isdigit (*buf); ++ buf); for (; isdigit (*buf); n = n * 10 + *buf - ‘0‘, ++ buf); } inline void Line (int x, int y, int z) { c[++ EC][0] = y, c[EC][1] = fi[x], fi[x] = EC, c[EC][2] = z; c[++ EC][0] = x, c[EC][1] = fi[y], fi[y] = EC, c[EC][2] = z; } struct Node { Node *c[2]; int v, s, val; }; Node pool[Max * 40], *unp[Max * 40], *Ta = pool, **top = unp, *_r[Max][2], Null, *null = &Null; struct Balance_Tree { inline Node* Get(int x) { Node *k = (top != unp) ? *--top : Ta ++; k->c[0] = k->c[1] = null, k->s = 1, k->v = x, k->val = rand (); return k; } inline void Update (Node *x) { x->s = x->c[0]->s + x->c[1]->s + 1; } Node *Rebuild (int x, int y) { Node* R = Get (dis[li[1]][y] - r[li[1]]); for (rg int i = 2; i <= x; ++ i) Inse_r (R, Get (dis[li[i]][y] - r[li[i]])); return R; } void Rotate (Node *&x, Node *y) { bool k = y == x->c[0]; x->c[!k] = y->c[k], y->c[k] = x, y->s=x->s; Update(x), x = y; return; } int Query (Node *x, int y) { if (x == null) return 0; if (y >= x->v) return x->c[0]->s + 1 + Query (x->c[1], y); return Query (x->c[0], y); } void Clear(Node* &x) { if (x == null) return; *top ++ = x, Clear (x->c[0]), Clear (x->c[1]), x = null; } void Inse_r (Node *&x, Node *y) { bool flag = y->v > x->v; if (x == null) { x = y; return; } else ++ x->s; Inse_r (x->c[flag], y); if (x->c[flag]->val > x->val) Rotate (x, x->c[flag]); } } B; #undef Max struct Divide_Tree { #define Max 100050 int suf[Max], ct[Max], sg[Max], s[Max], R, Sg; int Get_R (int C) { int _C = li[1]; rg int i, j; for (i = C; i >= 1; -- i) for (s[li[i]] = 1, j = fi[li[i]]; j; j = c[j][1]) if (!sg[c[j][0]] && s[c[j][0]] > 0) s[li[i]] += s[c[j][0]]; for (; true; ) { bool flag = false; for (i = fi[_C]; i; i = c[i][1]) if (s[c[i][0]] < s[_C] && !sg[c[i][0]] && s[c[i][0]] * 2 >= C) { _C = c[i][0], flag = true; break; } if (!flag) break; } for (i = 1; i <= C; ++ i) s[li[i]] = 0; return _C; } int Get_s (int x) { int le = 1, ri = 1; li[1] = x, s[x] = -1; for (rg int i; le <= ri; ++ le) for (i = fi[li[le]]; i; i = c[i][1]) if (!s[c[i][0]] && !sg[c[i][0]]) s[li[++ ri] = c[i][0]] = -1; return ri; } void Clear (int x) { if (!sg[x] || sg[x] < Sg) return; sg[x] = 0, B.Clear (_r[x][0]), B.Clear (_r[x][1]); for (rg int i = fi[x]; i; i = c[i][1]) Clear (c[i][0]); } void Get (int x, int y) { ct[x] = 1, sg[x] = sg[suf[x]] + 1; rg int i, j; int _f = 0; _r[x][0] = B.Get (-y), _r[x][1] = B.Get (c[EC][2] - y); memcpy (dis[x], dis[suf[x]], sizeof dis[suf[x]]); for (i = 1; i < sg[x]; ++ i) dis[x][i] += c[EC][2]; for (dis[x][sg[x]] = 0, i = suf[x], j = sg[x] - 1; i; i = suf[i], -- j) { ++ ct[i]; if (j - 1 && ct[i] / (ct[suf[i]] + 1.0) > EPS) _f = suf[i]; Answer += B.Query (_r[i][0], y - dis[x][j]), B.Inse_r (_r[i][0], B.Get (dis[x][j] - y)); if (j - 1) Answer -= B.Query (_r[i][1], y - dis[x][j - 1]), B.Inse_r (_r[i][1], B.Get (dis[x][j - 1] - y)); } if (_f) Sg = sg[_f], Clear (_f), Rebuild (_f, Sg, suf[_f]); } void Rebuild (int x, int y, int z) { int C = Get_s (x), _C = Get_R (C); dis[_C][y] = 0, Dfs (_C, 0, y), sg[_C] = y; if (z) suf[_C] = z; else suf[R = _C] = 0, _r[_C][1] = null; _r[_C][0] = B.Rebuild (C, y), ct[_C] = C; if (y > 1) _r[_C][1] = B.Rebuild (C, y - 1); for (rg int i = fi[_C]; i; i = c[i][1]) if (!sg[c[i][0]]) Rebuild (c[i][0], y + 1, _C); } void Dfs (int x,int y,int z) { for (rg int i = fi[x]; i; i = c[i][1]) if (!sg[c[i][0]] && c[i][0] != y) dis[c[i][0]][z] = dis[x][z] + c[i][2], Dfs (c[i][0], x, z); } #undef Max } A; int main (int argc, char *argv[]) { fread (buf, 1, BUF, stdin); read (Zero), read (N), read (Zero), read (Zero), A.R = 1; Null.c[0] = Null.c[1] = &Null; int q, w; srand (time (0)), read (r[1]), A.Get (1, r[1]); puts ("0"); for (rg int i = 2; i <= N; ++ i) { read (q), q = q ^ (Answer % (int) INF), read (w); read (r[i]), h[i] = h[q] + 1, d[i] = d[q] + w; Line (i, q, w), A.suf[i] = q, A.Get (i, r[i]); printf ("%lld\n", Answer); } return 0; }
时间: 2024-11-10 07:29:17