bzoj4771 dfs序 倍增 主席樹

2022-08-20 03:54:11 字數 1339 閱讀 3586

先考慮沒有深度限制的情況。

先將每個節點的權值設為1,對於顏色相同且在dfs序中最近的2個點,用倍增求出lca並將它的權值減一。然後子樹中不同的顏色種數就是子樹的權值和了。

有深度限制時,考慮以深度為時間建立主席樹。

將每個點按深度排序,列舉一遍。對每種顏色開乙個set,列舉到乙個點時將它在dfs序中的位置加入set中並更新就可以了。

時間複雜度o(t*(nlogn+mlogn))

**:

#include#include

#include

#include

#include

using

namespace

std;

inline

char

nc()

return *p1++;

}inline

void read(int&x)

#define n 100010

#define m 20

#define i set::iterator

struct

node1a[n*m<<2

];struct

edgee[n];

intx,y,num,i,j,k,n,t,cnt,m,d[n],rt[n],l[n],r[n],h[n],c[n],f[n][m],last;

struct

node3

node3(

int f,int

w):f(f),w(w){}

bool

operator

< (node3 x)const

}a[n],tmp;

sets[n];

inline

int _min(int x,int y)

inline

void add(int x,int y)

inline

void dfs(int

x)inline

void build(int& node,int l,int

r)inline

void insert(int l,int& node,int x,int l,int r,int

y)inline

int query(int node,int l,int r,int l,int

r)inline

int lca(int x,int

y)int

main()

}last=0

;

while(m--)

}return0;

}

bzoj4771

BZOJ 4771 主席樹 倍增 set

思路 但是發現這樣怎麼去維護lca呢.因為要求有序,所以我們可以用set來維護相同顏色的節點.如果把乙個點加入集合之後這個點前驅為x,後繼為y,那麼我們去修正,把xy的lca 1,然後x和當前點的lca 1,當前點和y的lca 1.from neighthorn by siriusren inclu...

BZOJ 4034 線段樹 DFS序

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

Bzoj 3991 尋寶遊戲 dfs序

小 b最近正在玩乙個尋寶遊戲,這個遊戲的地圖中有 n個村莊和 n 1條道路,並且任何兩個村莊之間有且僅有一條路徑可達。遊戲開始時,玩家可以任意選擇乙個村莊,瞬間轉移到這個村莊,然後可以任意在地圖的道路上行走,若走到某個村莊中有寶物,則視為找到該村莊內的寶物,直到找到所有寶物並返回到最初轉移到的村莊為...