[Bzoj 3626] [LNOI2014] LCA "tree chain split + offline + differential query"

Source: Internet
Author: User

Title Link: BZOJ-3626

Problem analysis

Considering this equivalence problem, if we assign a point x to the root of each point to the weight of 1, the remaining points of the weight of 0, then the Depth from the LCA (x, y) is from the Y to the root of the path on the right and the point.

This method can be superimposed, which is a very useful point. If we put [L, R] Each point to the root of all points on the path of the weight of +1, and then find the path from C to root of the right and, that is, [L, R] a bit with C of the LCA Depth and.

Not only to meet the additive, but also to meet the reduction, which is better!

Then we can make a difference to each inquiry [L, R], using query (r)-query (L-1) as the answer. Thus there is an off-line algorithm: N points in turn, to the root of the path of the point weight of +1, and if the point is a query l-1 or R, use the query C to find the path to Root and, in the answer.

done!

Forget the% Mod when you write the code is really weak ...

Code

#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath > #include <algorithm> #include <queue> #include <vector>using namespace Std;const int maxn = 50000 + 5  , Mod = 201314;int N, m, Index;int FATHER[MAXN], DEPTH[MAXN], SIZE[MAXN], SON[MAXN], TOP[MAXN], Pos[maxn];int T[MaxN * 4], D[MAXN * 4], LEN[MAXN * 4], ANS[MAXN], q[maxn];vector<int> BA[MAXN], ea[maxn];struct Edge {int v; Edge *next;} E[MAXN], *p = E, *point[maxn];inline void Addedge (int x, int y) {++p; P-v = y; P-Next = point[x]; POINT[X] = P;} int dfs_1 (int x, int Dep) {depth[x] = dep; SIZE[X] = 1;int sonsize, maxsonsize; Sonsize = Maxsonsize = 1;for (Edge *j = point[x]; j; j = J-Next) {sonsize = Dfs_1 (J-V, DEP + 1); if (Sonsize &G T maxsonsize) {maxsonsize = sonsize; SON[X] = J-V;} SIZE[X] + = sonsize;} return size[x];} void dfs_2 (int x) {if (x = = Son[father[x]]) top[x] = Top[father[x]];else top[x] = x; POS[X] = ++index;if (son[x]! = 0) dfs_2 (son[x]), for (Edge *j = point[x]; j; j = J-Next) if (J-V! = son[x]) dfs_2 (J-v);} void Build_tree (int x, int s, int t) {len[x] = t-S + 1;d[x] = t[x] = 0;if (s = = t) return;int m = (s + t) >> 1; Build_tree (x << 1, S, m); Build_tree (x << 1 | 1, M + 1, t);} inline void Update (int x) {T[x] = t[x << 1] + t[x << 1 | 1]; T[X]%= Mod;} inline void Paint (int x, int Num) {t[x] + = Num * Len[x]; T[X]%= mod;d[x] + + num;d[x]%= Mod;} inline void pushdown (int x) {if (d[x] = = 0) return; Paint (x << 1, d[x]); Paint (x << 1 | 1, d[x]);D [x] = 0;} void Add (int x, int s, int t, int l, int r) {if (L <= s && r >= t) {Paint (x, 1); return;} Pushdown (x); int m = (s + t) >> 1;if (L <= m) Add (x << 1, S, M, L, R); if (r >= m + 1) Add (x << 1 | 1, M + 1, T, L, R); Update (x);} void Eadd (int x) {int fx;fx = Top[x];while (FX! = 1) {ADD (1, 1, N, Pos[fx], pos[x]); x = Father[fx];fx = Top[x];} ADD (1, 1, N, Pos[1], pos[x]);} int Get (int x, int s, int t, int l, int r) {if (L <= s && r >= T) return t[x];int ret = 0;  Pushdown (x); int m = (s + t) >> 1;if (L <= m) ret + = Get (x << 1, S, M, L, R), if (R >= m + 1) ret + = Get (x << 1 | 1, M + 1, T, L, R); return ret% Mod;} int eget (int x) {int ret = 0, Fx;fx = top[x];while (FX! = 1) {ret + = Get (1, 1, N, Pos[fx], pos[x]); ret%= mod;x = father[f X];FX = Top[x];} RET + = Get (1, 1, N, Pos[1], pos[x]); return ret% Mod;} int main () {scanf ("%d%d", &n, &m); int A, B, c;for (int i = 2; I <= n; ++i) {scanf ("%d", &a); ++a; Father[i] = A; Addedge (A, i);} Dfs_1 (1, 1); Index = 0;dfs_2 (1); Build_tree (1, 1, n); for (int i = 1; I <= m; ++i) {scanf ("%d%d%d", &a, &b, &c); ++a; ++b; ++c; Q[i] = C;ba[a-1].push_back (i); Ea[b].push_back (i);} for (int i = 1; I <= n; ++i) {Eadd (i), for (int j = 0; J < ba[i].size (); ++j) Ans[ba[i][j]]-= Eget (Q[ba[i][j]]); for (int j = 0; J < ea[i].size (); ++j) ANS[EA[I][J]] + = Eget (Q[ea[i][j]);} for (int i =1; I <= m; ++i) printf ("%d\n", (Ans[i] + MoD)% mod); return 0;}

  

[Bzoj 3626] [LNOI2014] LCA "tree chain split + offline + differential query"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.