lg傳送門
點分治+線段樹合併。
我不會寫單調佇列,所以就寫了好寫的線段樹。
考慮對於每乙個分治中心,把出邊按顏色排序,這樣就能把顏色相同的子樹放在一起處理。用一棵動態開點線段樹維護顏色不同的子樹的資訊,另一棵動態開點線段樹維護顏色相同的子樹的資訊,同時按照題目要求更新答案。當子樹顏色變化時,就把第二棵線段樹合併到第一棵裡面去就好了。
**實現有點繁瑣,我調了很久。。。
#include#include#include#include#include#define r register
#define i inline
#define z first
#define y second
using namespace std;
const int s=200003,m=6000003,inf=0x3f3f3f3f;
char buf[1000000],*p1,*p2;
i char gc()
i int rd()
vector> g[s];
struct ta[m];
int c[s],s[s],t[s],h[s],v[s],n,m,e,l,u,u,r,o=-inf,a,b;
i int max(int x,int y)
i void add(int x,int y,int z)
i void ini()
int mrg(int k,int t)
void ins(int &k,int l,int r,int x,int v)
r int m=l+r>>1;
if(x<=m) ins(a[k].l,l,m,x,v);
else ins(a[k].r,m+1,r,x,v);
a[k].f=max(a[a[k].l].f,a[a[k].r].f);
}int qry(int k,int l,int r,int x,int y)
void dac(int x)
for(i=0;iif(!v[y=g[l][i].y])
dac(y);
}int main()
BJOI2017 樹的難題 點分治 線段樹
傳送門 傳送門 題意 給一棵樹,樹上有顏色,每種顏色有權值,定義一條路徑的權值為所有顏色相同段的權值之和,求長度在 l,r l,r l,r 中的路徑的最大權值。資料範圍 暴力過不了 顯然是個點分治 對於分治中心考慮過中心的路徑貢獻的答案 以下的 子樹 指根直接與分治中心相連的子樹 把分治中心作為根,...
BJOI2017 樹的難題
按照常規思路,選乙個點x作為分治中心,拼接x出發到子樹各點的路徑。對於拼接時兩段介面處 即x連出的那條邊,若沒有,設為0號邊 顏色為0,長度為0,到達0號兒子 顏色的影響,可以記錄每段的路徑權值 邊數以及該段的介面,將所有的路徑以介面顏色為第一關鍵字,介面編號為第二關鍵字排序。顯然,對於同一介面的路...
樹的點分治
codeforces 150e 通過點分治以及合併子樹檢查二分的答案 用深度從小到大的方式可以剪枝,達到nlog 2 n 的複雜度 不離散化常數巨大,離散化常數依然巨大 include include include include include define maxn 100005 define...