題意:
思路:總的來說,查詢區間第k小利用函式式線段樹的減法操作。對於兩棵樹的合併,將節點少的樹暴力插入到節點大的樹上面。對於本題,首先,將輸入的權值離散化,為已經給出的邊建立函式式線段樹。對於合併x,y,將y的父節點設為x,然後重新建立y為根的子樹的函式式線段樹。對於查詢x,y,k,設其lca為p,p的父節點為q,則x+y-p-q就是整個區間。
struct node;node tree[n*400];
int root[n],tot;
int f[n][20],w[n],n,m,k,d[n],size[n];
vectorg[n];
int m;
int b[n];
int build(int a,int b)
int insert(int c,int s,int a,int b)
int visit[n],x;
void bfs(int u)
}} int get(int x,int k)
return f[x][0];}
#define l(a) tree[tree[a].l].s
int query(int a,int b,int c,int d,int k,int l,int r)
void go()
else
else
}}}
int main()
for1(i,n) f[i][0]=-1;
for1(i,n) if(f[i][0]==-1)
go();
}
BZOJ 3123 森林 主席樹啟發式合併
第一行包含乙個正整數testcase,表示當前測試資料的測試點編號。保證1 testcase 20。第二行包含三個整數n,m,t,分別表示節點數 初始邊數 運算元。第三行包含n個非負整數表示 n個節點上的權值。接下來 m行,每行包含兩個整數x和 y,表示初始的時候,點x和點y 之間有一條無向邊,接下...
BZOJ3123 森林(主席樹,啟發式合併)
神tm題面是 首先,求樹鏈上第k大,請參看bzoj2588 count on a tree 這道題目於是增添了乙個動態的合併森林的操作 所以直接啟發式合併就可以啦 我第一次交直接t了 加了一堆rg就ac了。神奇的register include include include include inc...
BZOJ 3123 森林 主席樹啟發式合併
第一行包含乙個正整數testcase,表示當前測試資料的測試點編號。保證1 testcase 20。第二行包含三個整數n,m,t,分別表示節點數 初始邊數 運算元。第三行包含n個非負整數表示 n個節點上的權值。接下來 m行,每行包含兩個整數x和 y,表示初始的時候,點x和點y 之間有一條無向邊,接下...