先考慮沒有深度限制的情況。
先將每個節點的權值設為1,對於顏色相同且在dfs序中最近的2個點,用倍增求出lca並將它的權值減一。然後子樹中不同的顏色種數就是子樹的權值和了。
有深度限制時,考慮以深度為時間建立主席樹。
將每個點按深度排序,列舉一遍。對每種顏色開乙個set,列舉到乙個點時將它在dfs序中的位置加入set中並更新就可以了。
時間複雜度o(t*(nlogn+mlogn))
**:
#include#includebzoj4771#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;
}
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條道路,並且任何兩個村莊之間有且僅有一條路徑可達。遊戲開始時,玩家可以任意選擇乙個村莊,瞬間轉移到這個村莊,然後可以任意在地圖的道路上行走,若走到某個村莊中有寶物,則視為找到該村莊內的寶物,直到找到所有寶物並返回到最初轉移到的村莊為...