傳送門
題解:按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...