中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP樹鏈剖分+函數式線段樹代碼怎么寫

發布時間:2022-04-06 16:40:15 來源:億速云 閱讀:122 作者:iii 欄目:編程語言

本篇內容介紹了“PHP樹鏈剖分+函數式線段樹代碼怎么寫”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
#define MID ( (l+r)>>1 )
#pragma comment(linker, "/STACK:1024000000,1024000000")
const int MAXN = 100005;
map<int,int> mp;
int itp[MAXN];
struct _edge
{
    int v, next;
    _edge(int _v=0, int _next=-1):v(_v),next(_next) {}
};
struct _seg
{
    int l, r;
    _seg(int ll=0, int rr=0):l(ll),r(rr) {}
} seg[MAXN];
int ns;
struct FTree
{
    FTree* ch[2];
    int siz;
} *root[MAXN], da[MAXN*50], *nf;
void build(FTree *& cur, int l, int r)
{
    cur = nf++;
    cur->siz = 0;
    if (l == r)
        return;
    int m = MID;
    build(cur->ch[0], l,m);
    build(cur->ch[1], m+1,r);
}
int query(FTree* LF, FTree* RT, int L, int R, int l, int r)
{
    if (L <= l && R >= r)
        return RT->siz-LF->siz;
    int res = 0;
    int m = MID;
    if (L <= m)
        res += query(LF->ch[0], RT->ch[0], L,R,l,m);
    if (R > m)
        res += query(LF->ch[1], RT->ch[1], L,R,m+1,r);
    return res;
}
struct node
{
    int head[MAXN], cnt, n;
    _edge e[MAXN];
    int son[MAXN], siz[MAXN], top[MAXN], fa[MAXN], dep[MAXN], pos[MAXN], np;
    void clear()
    {
        cnt = 0;
        memset(head, -1, sizeof head);
        np = 0;
    }
    void add(int u, int v)
    {
        e[cnt] = _edge(v, head[u]);
        head[u] = cnt++;
    }
    void dfs1(int u, int pre)
    {
        fa[u] = pre;
        dep[u] = dep[pre] + 1;
        siz[u] = 1;
        son[u] = 0;
        for (int i = head[u]; ~i; i=e[i].next)
        {
            int v = e[i].v;
            dfs1(v, u);
            siz[u] += siz[v];
            if (siz[son[u]] < siz[v])
                son[u] = v;
        }
    }
    void dfs2(int u, int pre)
    {
        top[u] = pre;
        pos[u] = ++np;
        if (!son[u]) return;
        dfs2(son[u], pre);
        for (int i = head[u]; ~i; i = e[i].next)
        {
            int v = e[i].v;
            if ( v!=son[u])
                dfs2(v, v);
        }
    }
    void search(int u, int v)
    {
        while (top[u] != top[v])
        {
            if (dep[top[u]] > dep[top[v]]) swap(u,v);
            seg[ns++] = _seg(pos[top[v]], pos[v]);
            v = fa[top[v]];
        }
        if (dep[u] > dep[v]) swap(u, v);
        seg[ns++] = _seg(pos[u], pos[v]);
    }
    int solve(int u, int v, _seg seg[], int m)
    {
        int res = 0;
        while (top[u] != top[v])
        {
            if (dep[top[u]] > dep[top[v]]) swap(u,v);
            for (int i = 0; i< ns; ++i)
                res += query(root[pos[top[v]]-1], root[pos[v]], seg[i].l, seg[i].r, 1, m);
            v = fa[top[v]];
        }
        if (dep[u] > dep[v]) swap(u, v);
        for (int i = 0; i< ns; ++i)
            res += query(root[pos[u]-1], root[pos[v]], seg[i].l, seg[i].r, 1, m);
        return res;
    }
} NA, NB;

void insert(FTree* &cur, FTree* old, int x, int l, int r)
{
    cur = nf++;
    if (l == r)
    {
        cur->siz = old->siz + 1;
        return;
    }
    int m = MID;
    if (x <= m)
    {
        cur->ch[1] = old->ch[1];
        insert(cur->ch[0], old->ch[0], x, l, m);
    }
    else
    {
        cur->ch[0] = old->ch[0];
        insert(cur->ch[1], old->ch[1], x, m+1,r);
    }
    cur->siz = cur->ch[0]->siz + cur->ch[1]->siz;
}
void init()
{
    NA.clear();
    NB.clear();
    mp.clear();
    nf = da;
    memset(root, 0, sizeof root);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int u, q, v, a, b;
    while (scanf("%d", &NA.n) != EOF)
    {
        init();
        for (int i = 1; i< NA.n; ++i)
        {
            scanf("%d", &u);
            NA.add(u, i+1);
        }
        NA.dfs1(1, 0);
        NA.dfs2(1, 1);
        for (int i = 1; i<= NA.n; ++i)
            scanf("%d", &u), mp[u] = NA.pos[i];
        scanf("%d", &NB.n);
        for (int i = 1; i< NB.n; ++i)
        {
            scanf("%d", &u);
            NB.add(u, i+1);
        }
        NB.dfs1(1, 0);
        NB.dfs2(1, 1);
        for (int i = 1; i<= NB.n; ++i)
        {
            scanf("%d", &u);
            itp[NB.pos[i]] = mp.count(u)?mp[u]:0;
        }
        build(root[0], 1, NA.n);
        for (int i = 1; i<= NB.n; ++i)
        {
            if (itp[i])
                insert(root[i], root[i-1], itp[i], 1, NA.n);
            else
                root[i] = root[i-1];
        }
        scanf("%d", &q);
        while (q--)
        {
            scanf("%d%d%d%d", &u, &v, &a, &b);
            ns = 0;
            NA.search(u, v);
            printf("%d\n", NB.solve(a, b, seg, NA.n));
        }
    }
    return 0;
}

“PHP樹鏈剖分+函數式線段樹代碼怎么寫”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

光泽县| 沧州市| 吉水县| 沁源县| 池州市| 东丽区| 宝鸡市| 茂名市| 慈溪市| 三原县| 松阳县| 荔波县| 延吉市| 称多县| 宜春市| 东乡族自治县| 新邵县| 阿瓦提县| 阿巴嘎旗| 惠水县| 海南省| 嘉义市| 农安县| 上杭县| 遂昌县| 响水县| 宁阳县| 蕲春县| 福鼎市| 宿松县| 迁西县| 尖扎县| 巨野县| 大石桥市| 玉屏| 犍为县| 孝义市| 沾益县| 张家港市| 桃园县| 常熟市|