思路:
但是發現這樣怎麼去維護lca呢...因為要求有序,所以我們可以用set來維護相同顏色的節點...如果把乙個點加入集合之後這個點前驅為x,後繼為y,那麼我們去修正,把xy的lca+1,然後x和當前點的lca-1,當前點和y的lca-1...
from neighthorn
//by siriusren
#include #include
#include
#include
using
namespace
std;
const
int n=100050
;int n,m,cases,v[n],next[n],first[n],tot,fa[n][20
],dfn[n],cnt,root[n],lst[n],dep[n];
int tree[n*50],lson[n*50],rson[n*50
],xx,yy,ans;
struct nodenode[n];
bool cmp(node a,node b)
bool cmp2(node a,node b)
struct cmp};
sets[n];set
::iterator it,it2,it3;
void add(int x,int y)
void dfs(int
x)void insert(int l,int r,int &pos,int last,int num,int
wei)
int query(int l,int r,int pos,int l,int
r)int lca(int x,int
y)int
main()
while(m--)
for(int i=1;i<=n;i++)s[i].clear(),root[i]=0
; }
}
主席樹 BZOJ 4771 七彩樹
感謝帶我飛的rxd大爺 我們先考慮不管深度限制可修改我們怎麼做 就是把每種顏色按照dfs序排列 然後給這些點都 1 但是相鄰兩個的lca處要 1 這樣子樹不同顏色數就是子樹和 然後我們把深度限制 看做按照深度的順序加點 加點我們需要維護什麼 每種顏色的序列 這個用set或平衡樹 在序列中插入 我們對...
BZOJ4771 七彩樹(主席樹)
點此看題面 考慮乙個子樹內所有點 dfs 序是連續的,所以我們可以將其轉化為序列然後用線段樹維護。又由於有深度限制,所以可以對不同深度建不同版本,使用主席樹。但是,本質不同顏色應該如何維護?考慮對於每一種顏色,如果有兩個該顏色的點同時出現,則相當於將這兩個點的權值分別加 1 而把它們 lca 的權值...
bzoj4771 dfs序 倍增 主席樹
先考慮沒有深度限制的情況。先將每個節點的權值設為1,對於顏色相同且在dfs序中最近的2個點,用倍增求出lca並將它的權值減一。然後子樹中不同的顏色種數就是子樹的權值和了。有深度限制時,考慮以深度為時間建立主席樹。將每個點按深度排序,列舉一遍。對每種顏色開乙個set,列舉到乙個點時將它在dfs序中的位...