給定一棵
n 個點的無根樹,樹上每一條邊都有顏色。一共
m種顏色,編號從
1 到m。第
i 種顏色權值為ci
。 對於樹上的一條簡單路徑,路徑上經過的所有邊按照順序組成乙個顏色序列,序列可以劃分成若干個相同顏色段。定義路徑權值為顏色序列上每乙個同顏色段的顏色權值之和。
你要計算出邊數在[l
,r] 之內的所有簡單路徑中,路徑權值的最大值。1≤
m≤n≤
2×105
,1≤l
≤r≤n
,|ci
|≤104
點分治,對於乙個分治重心,把子樹按照到重心邊的顏色排序,然後同種顏色同種顏色轉移,用線段樹記錄長度為某個值的最大答案,開兩棵來進行不同顏色和同顏色的轉移。在切換顏色時使用線段樹合併將第二棵並到第一棵上可以卡常。
時間複雜度o(
nlog2n
) 。
然而,如果我們同顏色按深度排排序,不同顏色也排排序,姿勢好一點的話用單調佇列可以做到o(
nlogn)
。蒟蒻在模擬賽時只想到了
log2
做法。
#include
#include
#include
#include
#include
using
namespace
std;
int read()
const
int inf=int_max;
const
int n=200050;
const
int m=200050;
const
int e=n<<1;
const
int lgn=18;
const
int s=n*lgn*2;
struct segment_tree
int newnode()
void insert(int &rt,int x,int y,int l,int r)
int query(int rt,int st,int en,int l,int r)
int merge(int rt1,int rt2)
}t;struct data
int core(int og)
void calc(int x,int len,int lst,int cur)
for (int i=last[x],y;i;i=nxt[i])
if ((y=tov[i])!=fa[x]&&!vis[y])
fa[y]=x,calc(y,len+1,col[i],cur+(lst!=col[i])*val[col[i]]);
}void change(int x,int len,int lst,int cur)
void solve(int x)
vis[c]=1;
for (int i=last[c],y;i;i=nxt[i])
if (!vis[y=tov[i]]) solve(y);
}int main()
1900 985的「樹」難題
time limit 1 sec memory limit 128 mb 985給你一棵 樹 以及它的根節點,要求你先判定它是否是一棵樹,其次他想知道每個節點的 太子 數目以及它的父親 root的話輸出自己 太子判定條件 一 若x是y的孩子節點,那麼x是y的 太子 二 若x是y的 太子 且y是z的 ...
G 樹的難題
時間限制 10000 ms 空間限制 165536 kb 評測說明 1s,128m 問題描述 給出乙個無根樹。樹有n個點,邊有權值。每個點都有顏色,是黑色 白色 灰色這三種顏色之一,稱為一棵三色樹。可愛的alice覺得,乙個三色樹為均衡的,當且僅當,樹中不含有黑色結點或者含有至多乙個白色節點。然而,...
jzoj3555 樹的直徑
科學家在觀測一棵大樹,這棵樹在不斷地生長,科學家給這棵樹的每個節點編了號。開始的時候,這棵樹很小只有4個節點,一號點為根,其他三個節點掛在上面。在接下來的m次觀察中,科學家每次都能看見這棵樹從葉子處長出新的兩個節點來。如果當前這棵樹有n個節點,那麼這棵樹的新的兩個節點的編號分別為n 1,n 2。科學...