bzoj 1803(DFS序 主席樹)

2021-08-08 04:49:31 字數 1042 閱讀 6726

傳送門

題解:按dfs序下標建主席樹,然後就不用說什麼了吧。。。

注意:如果詢問/插入的[l,r]是[0,1e9]的話,就需要多開陣列(maxn*32),而且效率不太高,所以建議先離散化,這樣就可以在[0,maxn]的範圍內詢問/插入,而且時間可以縮短10%左右。

#include

using namespace std;

const int maxn=1e5+4;

int n,q,a[maxn],b[maxn],in[maxn],out[maxn],tot=0;

int root[maxn]=,lc[maxn*18],rc[maxn*18],sum[maxn*18],rk[maxn*18],tim=0;

int head[maxn],edge=0;

struct edge e[maxn<<1];

inline int

read()

while (c>='0'&&c<='9') x=x

*10+c-'0',c=getchar();

returnx;}

inline void adde(int u,int v)

void insert(int pre,int &rt,int l,int r,int val,int id)

lc[rt]=lc[pre],rc[rt]=rc[pre];

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

if (val<=mid) insert(lc[pre],lc[rt],l,mid,val,id);

else insert(rc[pre],rc[rt],mid+1,r,val,id);

}int query(int pre,int now,int l,int r,int k)

void dfs(int p,int fa)

out[p]=tot;

}int main()

dfs(1,0);

q=read();

for (register int r=0;rreturn

0;}

bzoj4771 dfs序 倍增 主席樹

先考慮沒有深度限制的情況。先將每個節點的權值設為1,對於顏色相同且在dfs序中最近的2個點,用倍增求出lca並將它的權值減一。然後子樹中不同的顏色種數就是子樹的權值和了。有深度限制時,考慮以深度為時間建立主席樹。將每個點按深度排序,列舉一遍。對每種顏色開乙個set,列舉到乙個點時將它在dfs序中的位...

SWERC 2016 F題(dfs序 主席樹)

題意 乙個有n個節點的樹,每個節點有等級和權值,問每個節點的子樹中等級比它小的節點的權值和。思路 先求出這棵樹的dfs序,再對dfs序建立主席樹,然後對每個節點查詢 include include include include using namespace std typedef long lo...

BZOJ 4034 線段樹 DFS序

思路 先搞出來每個點的dfs序 要有入棧和出棧兩種狀態的 處理出來 線段樹區間有多少入棧的和多少出棧的 加區間的時候就加 入 出 wei 查字首和 by siriusren include include include using namespace std define n 200050 def...