日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【APIO2016】Fireworks【闵可夫斯基和】【凸包向量和】【可并堆】

發(fā)布時(shí)間:2023/12/4 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【APIO2016】Fireworks【闵可夫斯基和】【凸包向量和】【可并堆】 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題意:給一棵帶邊權(quán)的樹(shù),可以花費(fèi) 111 的代價(jià)把一條邊的邊權(quán)修改 111,一條邊可以修改多次,求使得根到葉子距離相等的最小代價(jià)。

n≤3×105n\leq 3\times 10^5n3×105

先暴力 dp

設(shè) f(u,k)f(u,k)f(u,k) 表示 uuu 到子樹(shù)內(nèi)所有葉子距離為 kkk 的最小代價(jià)。因?yàn)槿匀挥卸喾N,所以最小是有意義的。

加入一個(gè)兒子 vvv 后,設(shè)這條邊長(zhǎng)度為 xxx

f(u,k)?f(u,k)+min?{∣i?x∣+f(v,k?i)}f(u,k)\longleftarrow f(u,k)+\min\{|i-x|+f(v,k-i)\} f(u,k)?f(u,k)+min{i?x+f(v,k?i)}

發(fā)現(xiàn)這東西就是 ∣x?i∣|x-i|x?ifvf_vfv? 做閔可夫斯基和,所以歸納法證明是個(gè)凸包。

然后 ∣x?i∣|x-i|x?i 這個(gè)東西相當(dāng)于是一段 (x,?x)(x,-x)(x,?x) 的向量和斜率為 111 的一條射線,因?yàn)橥拱甭识际钦麛?shù),相當(dāng)于找到斜率為 000 的這一段,將它和它右邊的向右下分別移動(dòng) xxx,然后右邊替換為斜率為 111 的射線。

然后是后面的凸包向量和,我們按從大到小維護(hù)凸包的所有頂點(diǎn)的橫坐標(biāo),并規(guī)定每經(jīng)過(guò)一個(gè)點(diǎn)斜率會(huì)減小 111,顯然最開(kāi)始的斜率是 111。那么凸包向量和就是所有頂點(diǎn)的可重并集。(一個(gè)點(diǎn)出現(xiàn)兩次說(shuō)明斜率變化了 222

用可并堆維護(hù)即可。最后得到了根的凸包,它的截距是所有邊的和,然后就可以推出答案。

復(fù)雜度 O(nlog?n)\Omicron(n\log n)O(nlogn)

#include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <vector> #define MAXN 600005 using namespace std; typedef long long ll; inline int read() {int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans; } int ch[MAXN][2],fa[MAXN],tot; ll val[MAXN]; int find(int x){return fa[x]==x? x:fa[x]=find(fa[x]);} int merge(int x,int y) {if (!x||!y) return x|y;if (val[x]<val[y]) swap(x,y);fa[ch[x][1]=merge(ch[x][1],y)]=x;swap(ch[x][0],ch[x][1]);return x; } inline void insert(int& x,int v){val[++tot]=v,x=merge(x,tot);} inline void erase(int& x){fa[ch[x][0]]=ch[x][0],fa[ch[x][1]]=ch[x][1],x=fa[x]=merge(ch[x][0],ch[x][1]);} vector<int> e[MAXN]; int c[MAXN],rt[MAXN]; void dfs(int u) {if (!e[u].size()) return insert(rt[u],c[u]),insert(rt[u],c[u]);for (int i=0;i<(int)e[u].size();i++){dfs(e[u][i]);rt[u]=merge(rt[u],rt[e[u][i]]);}for (int i=0;i<(int)e[u].size()-1;i++) erase(rt[u]);int x,y;x=rt[u],erase(rt[u]);y=rt[u],erase(rt[u]);val[x]+=c[u],val[y]+=c[u];ch[x][0]=ch[x][1]=ch[y][0]=ch[y][1]=0;fa[x]=x,fa[y]=y;rt[u]=merge(rt[u],x);rt[u]=merge(rt[u],y); } int main() {int n=read()+read();ll sum=0;for (int i=1;i<=n;i++) fa[i]=i;for (int i=2;i<=n;i++) e[read()].push_back(i),sum+=c[i]=read();dfs(1);int las=rt[1],k=0;while (rt[1]){erase(rt[1]);int cur=rt[1];sum-=k*(val[las]-val[cur]);las=cur,++k;}cout<<sum;return 0; }

總結(jié)

以上是生活随笔為你收集整理的【APIO2016】Fireworks【闵可夫斯基和】【凸包向量和】【可并堆】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。