首先要明確一點,答案分布是有單調性的。什麼意思呢?假設我們的答案在 \(u\) 節點,\((u,v)\) 之間有一條邊且 \(u\) 離答案所在的點更近,那麼 \(u\) 節點作為答案一定不比在 \(v\) 節點作答案劣。從鏈的角度分析在拓展到樹上會比較好理解這個性質。
那麼如果樹是一棵完全二叉樹,就可以 \(\log n\) 的回答了。從根節點向下跳,每次如果找到乙個 \(\displaystyle2*sum[u]\geq tot\) (\(sum[u]\) 為 \(u\) 子樹點權之和, \(tot\) 為整張圖點權之和)的節點,就說明存在乙個更優或不劣的答案,就往這個方向跳,直到不能跳為止。更新時直接暴力修改父親,沒什麼可說的。
雖然這棵樹不一定是完全二叉樹,但是這棵樹的「分治樹」高度一定是不超過 \(\log n\) 的(我個人不習慣使用「分治樹」的概念,而將點分治理解為重心管轄區域這樣的概念)。那麼就對這棵樹進行點分,存下每個數對應的每一層重心對應容器的標號,到它的距離,以及是容是斥。此題的每層重心的容器就是兩個變數 \(sum,sum\) ,其中 \(sum\) 表示此重心管轄區域權值乘距離總和,\(sum\) 表示權值總和。那麼對於 \(u\) 一層重心對應容器編號為 \(id\) ,距離 \(dis\) ,容斥係數為 \(s\) ,產生貢獻即為 \(s(sum[id]+dis\cdot sum[id])\) 。那麼就能 \(o(\log n)\) 的詢問取某個點的答案是多少了。
修改仍為暴力修改,沒什麼好說的。
關鍵在於回答詢問,我們從整張圖的重心 \(u\) 開始跳,這個重心 \(u\) 將樹劈成了若干個連通塊(題目有條件,最多 \(20\) 個),對於其中乙個連通塊,我們設 \(v\) 在這個連通塊內且與 \(u\) 有邊。我們查詢選 \(v\) 的得到的答案,如果小於等於 \(u\) 的答案,那麼就要跳了。妙的是這裡跳的是這個連通塊的重心 \(w\),這樣就可以保證複雜度了。所以,在點分的時候就要順便把每個層重心 \(u\) 的下層重心 \(w\) ,以及對應的 \(v\) 存下來。複雜度 \(o(20 \cdot n\log ^2n)\) ,還是挺飄的。
#include#define for(i,x,y) for(int i=(x),i##end=(y);i<=i##end;++i)
#define dor(i,x,y) for(int i=(x),i##end=(y);i>=i##end;--i)
using namespace std;
templateinline bool chk_min(t &x,const _t y)
void clear()
void add(int u,int v,int w)
#define eor(i,g,u) for(int i=g.head[u];~i;i=g.nxt[i])
};linked_listg,h;
ll sum[n*2],sum[n*2];int sc;
int lv[n],sid[n][40];ll dis[n][40];bool sgn[n][40];
int sz[n];bool mark[n];
int n,q;
void cfs(int u,int f,int tot,int &c,int &mi)
res=max(res,tot-sz[u]);
if(chk_min(mi,res))c=u;
}void dfs_init(int u,int f,ll d,bool s)
}void dac(int u,int f,int tot)
}void update(int u,int val)
}ll query(int u)
return res;
}ll query(int u)
return res;
}int main()
int c,mi=1e9;
cfs(1,0,n,c,mi);
memset(mark,0,sizeof(mark));
memset(lv,0,sizeof(lv));
sc=0;
dac(1,0,n);
while(q--)
return 0;
}
ZJOI2015 幻想鄉戰略遊戲
題意 求乙個樹的帶權重心,帶修改。現在首位的題解的方法太噁心了,這裡介紹我自己的理解。假設重心為 x 我們有它的代價為 sum limits operatorname i,x times val i 其中 val i 表示 i 節點的權值。那如果將重心向 x 的某乙個相鄰節點 y 移動一格的話,設 ...
ZJOI2015 諸神眷顧的幻想鄉
p3256 zjoi2015 day1 諸神眷顧的幻想鄉 時間限制 20000 ms 空間限制 524288 kb 問題描述 幽香是全幻想鄉里最受人歡迎的萌妹子,這天,是幽香的2600歲生日,無數幽香的粉絲到了幽香家門前的太陽花田上來為幽香慶祝生日。粉絲們非常熱情,自發組織表演了一系列節目給幽香看。...
ZJOI2015 諸神眷顧的幻想鄉
一行乙個整數表示答案 7 3 0 2 1 2 1 0 0 1 2 3 4 3 5 4 6 5 7 2 5n 100000,c 10 發現葉子只有10個,那麼可以以每個葉子為根,建trie,然後建廣義字尾自動機 對於每個狀態,代表的字串個數就是max min 1 include include inc...