您好,登錄后才能下訂單哦!
本篇內容介紹了“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樹鏈剖分+函數式線段樹代碼怎么寫”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。