LCA 樹鏈剖分 線段樹

2022-03-19 18:55:39 字數 1979 閱讀 5207

給出乙個 \(n\) 個節點的有根樹(編號為 \(0\) 到 \(n-1\),根節點為 \(0\))。乙個點的深度定義為這個節點到根的距離 \(+1\) 。

設 \(dep[i]\) 表示點 \(i\) 的深度,\(lca(i,j)\) 表示 \(i\) 與 \(j\) 的最近公共祖先。

有 \(q\) 次詢問,每次詢問給出 \(l,r,z\),求 \(∑_^​dep[lca(i,z)]\) 。

(即,求在 \([l,r]\) 區間內的每個節點i與z的最近公共祖先的深度之和)

第一行 \(2\) 個整數 \(n,q\)。

接下來 \(n-1\) 行,分別表示點 \(1\) 到點 \(n-1\) 的父節點編號。

接下來 \(q\) 行,每行 \(3\) 個整數 \(l,r,z\)。

輸出 \(q\) 行,每行表示乙個詢問的答案。每個答案對 \(201314\) 取模輸出

樣例輸入

5 200

111 4 3

1 4 2

樣例輸出
8

5

共 \(10\) 組資料,\(n\) 與 \(q\) 的規模分別為 \(1000,2000,3000,4000,5000,10000,20000,30000,40000,50000\)。

#include#include#include#include#include#define r register

#define n 200010

#define int long long

using namespace std;

inline int read()

while(ch>='0'&&ch<='9')

return x*f;

}const int mod = 201314;

int n,q,dep[n],f[n],siz[n],son[n],dfn[n],cnt,top[n],head[n],ans[n];

int tr[n<<2],tag[n<<2];

struct edgee[n<<1];

struct problem

problem(int _pos,int _z,int _id,int _flag)

bool operator <(const problem &a)const

}ask[n<<1];

int len;

void addedge(int u,int v)

void dfs(int u,int fa)

}void dfs2(int u,int tp)

}#define ls rt<<1

#define rs rt<<1|1

inline void pushdown(int rt,int l,int r)

}void update(int rt,int l,int r,int s,int t)

pushdown(rt,l,r);

int mid = (l+r)>>1;

if(s<=mid)update(ls,l,mid,s,t);

if(t>mid)update(rs,mid+1,r,s,t);

tr[rt] = tr[ls]+tr[rs];

}int query(int rt,int l,int r,int s,int t)

void modify(int u,int v)

int getsum(int u,int v)

signed main()

dfs(1,0);

dfs2(1,0);

int tot = 0;

for(int i = 1;i <= q;i++)

sort(ask,ask+tot);

int cur = 1;

for(int i = 0;i < tot;i++)

for(int i = 1;i <= q;i++)

return 0;

}

poj 3237 樹鏈剖分 線段樹

題意 給一棵樹,三種操作。將第i條邊的權值改為v,將a到b的路徑上的邊的權值全部取反,求a到b路徑上邊的權值的最大值。思路 明顯的樹鏈剖分,加上線段樹的操作。因為有取反的操作所以每個區間要記錄最大值和最小值。查詢兩點間的路徑時,用求公共祖先的方式去求。include include includec...

hdu 3966(樹鏈剖分 線段樹)

題意 給出一棵樹,每個節點有一些敵人,有三種操作,i x,y,路徑上的所有點的人數 w。d x,y,路徑上的所有點的人數 w。q 節點x的人數。pragma comment linker,stack 1024000000,1024000000 include include include usin...

poj 3237 樹鏈剖分 線段樹

題意就是給你一棵樹,每條邊上都有權值,有三種操作,把某條邊的權值變成v,把點a到點b之間的路徑上的邊的權值都乘上 1,求a到b的路徑上的最大值。其實這題的線段樹要比樹鏈剖分難寫,首先,因為有乘 1的操作,所以不光要維護最大值,還要維護最小值,這樣在乘 1後,最大值就可以直接根據最小值得到,當然,延遲...