Bzoj 3626 LCA

Source: Internet
Author: User

At first glance, I think this question is only offline. We can find all F (1, I, Z). The answer is equivalent to F (1, R, Z)-f (1, l-1, Z ). However, there is no specific method, but the depth of the LCA and there is a very clever way. Each time a vertex is added, the vertex weight from this vertex to the root path is + 1, in this way, we can calculate the LCA depth of a certain point and all previous points, and calculate the weights and values of the points on the path of the point to the root. In this way, we can use the tree link to quickly modify and obtain the answer, which solves the problem.

Code:

#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <queue>#define N 51000#define yu 201314using namespace std;struct sss{    int place, askp;    int num, nump;}ask[N*2];struct ss{    int num, push;}t[N*4];int n, m, nowplace = 0;int p[N], v[N], next[N], bnum = 0;int ans[N][2] = {0};int fa[N], deep[N], siz[N], son[N], w[N], top[N];bool cmp(sss x, sss y) { return x.place < y.place; }void addbian(int x, int y){    bnum++; next[bnum] = p[x]; p[x] = bnum; v[bnum] = y;}void build_tree(int now, int l, int r){    t[now].num = 0; t[now].push = 0;    if (l == r) return; int mid = (l+r)/2;    build_tree(now*2, l, mid); build_tree(now*2+1, mid+1, r);}void dfs_1(int now, int fat, int de){    int k = p[now]; fa[now] = fat; deep[now] = de;    int maxsonnum = 0; siz[now] = 1; son[now] = 0;    while (k)    {        if (v[k] != fat)        {            dfs_1(v[k], now, de+1);            siz[now] += siz[v[k]];            if (siz[v[k]] > maxsonnum)            {                maxsonnum = siz[v[k]];                son[now] = v[k];            }        }        k = next[k];    }    return;}void dfs_2(int now, int fat, int nowtop){    int k = p[now]; top[now] = nowtop; w[now] = ++nowplace;    if (son[now]) dfs_2(son[now], now, nowtop);    while (k)    {        if (v[k] != son[now] && v[k] != fat)            dfs_2(v[k], now, v[k]);        k = next[k];    }    return;}void downdate(int now, int l, int r){    if (!t[now].push) return; int mid = (l+r)/2;    t[now*2].push += t[now].push;    t[now*2+1].push += t[now].push;    t[now*2].num += (mid-l+1) * t[now].push;    t[now*2+1].num += (r-mid) * t[now].push;    if (t[now*2].num > yu) t[now*2].num %= yu;    if (t[now*2+1].num > yu) t[now*2+1].num %= yu;    t[now].push = 0; return;}void tadd(int now, int l, int r, int al, int ar){    if (al <= l && r <= ar)    {        t[now].num += r-l+1;        if (t[now].num > yu) t[now].num %= yu;        t[now].push ++; return;    }    int mid = (l+r)/2; downdate(now, l, r);    if (al <= mid) tadd(now*2, l, mid, al, ar);    if (ar > mid) tadd(now*2+1, mid+1, r, al, ar);    t[now].num = t[now*2].num + t[now*2+1].num;    if (t[now].num > yu) t[now].num %= yu;}int task(int now, int l, int r, int al, int ar){    if (al <= l && r <= ar) return t[now].num;    int mid = (l+r)/2, zans = 0; downdate(now, l, r);    if (al <= mid) zans = task(now*2, l, mid, al, ar);    if (ar > mid) zans += task(now*2+1, mid+1, r, al, ar);    if (zans > yu) zans %= yu;    return zans;}int askk(int u, int v){    int f1 = top[u], f2 = top[v];    if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); }    if (f1 == f2)    {        if (u == v) return task(1, 1, n, w[u], w[u]);        return task(1, 1, n, min(w[u], w[v]), max(w[u], w[v]));    }    int zans = task(1, 1, n, w[f1], w[u]);    zans += askk(fa[f1], v); if (zans > yu) zans %= yu;    return zans;}void add(int u, int v){    int f1 = top[u], f2 = top[v];    if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); }    if (f1 == f2)    {        if (u == v) tadd(1, 1, n, w[u], w[u]);        else tadd(1, 1, n, min(w[u], w[v]), max(w[u], w[v]));        return;    }    tadd(1, 1, n, w[f1], w[u]); add(fa[f1], v);}int main(){    scanf("%d%d", &n, &m); build_tree(1, 1, n);    for (int i = 1; i < n; ++i)    {        int x; scanf("%d", &x);        addbian(x+1, i+1);    }    dfs_1(1, 0, 1); dfs_2(1, 0, 1);    for (int i = 1; i <= m; ++i)    {        int x, y, z; scanf("%d%d%d", &x, &y, &z); x++; y++; z++;        ask[i*2-1].place = x-1; ask[i*2-1].askp = z;        ask[i*2-1].num = i; ask[i*2-1].nump = 0;        ask[i*2].place = y; ask[i*2].askp = z;        ask[i*2].num = i; ask[i*2].nump = 1;    }    sort(ask+1, ask+1+2*m, cmp); int nowplace = 0;    for (int i = 1; i <= m*2; ++i)    {        while (ask[i].place > nowplace)        {            nowplace++;            add(1, nowplace);        }        if (ask[i].place)            ans[ask[i].num][ask[i].nump] = askk(1, ask[i].askp);        else ans[ask[i].num][ask[i].nump] = 0;    }    for (int i = 1; i <= m; ++i)        printf("%d\n", (ans[i][1]+yu-ans[i][0]) % yu);    return 0;}

 

Bzoj 3626 LCA

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.