P4103 HEOI2014 大工程 (虛樹)

2022-05-27 18:15:12 字數 1673 閱讀 1660

觀察資料範圍是跟k有關的,因此我們考慮建立虛樹,對於維護三個值

總和就是常規的按每條路左右兩邊點數算貢獻,注意是特殊點的數量

之後我們維護mi[i],mx[i]表示對於當前點,子樹中離他最近的特殊點在哪

#includeusing

namespace

std;

typedef

long

long

ll;typedef unsigned

long

long

ull;

typedef pair

pll;

const

int n=2e6+10

;const

int m=2e6+10

;const

int inf=0x3f3f3f3f

;const ll mod=998244353

;struct

node;

vector

g[n],g1[n];

intdfn[n],times,depth[n];

int n,f[n][25],cost[n][25

];int

st[n];

intcnt[n];

ll sz[n];

intq[n],k;

ll dp[n][

2],sum,mi,mx;

ll ans1[n],ans2[n];

void dfs(int u,int

fa,ll w)

for(i=0;i)

}bool cmp(int a,int

b)int lca(int a,int

b) }

if(a==b)

return

a;

for(i=21;i>=0;i--)

}return f[a][0];}

ll query(

int a,int

b) }

return

ans;

}void add(int a,int

b));

}void

get(int u,int

fa)

else

for(i=0;i)

g[u].clear();

}int

main());

g1[b].push_back();

}dfs(

1,0,0

);

intm;

cin>>m;

while(m--)

sort(cnt+1,cnt+1+k,cmp);

q[1]=1

;

int tt=1

;

for(i=1;i<=k;i++)

if(dfn[p]!=dfn[q[tt-1

]])

else

}q[++tt]=cnt[i];

}for(i=1;i)

sum=0,mi=1e18,mx=-1e18;

get(1,-1

); cout""

st[1]=0

; }

return0;

}

view code

P4103 HEOI2014 大工程 虛樹

虛樹板題一道。個人覺得這題比 消耗戰 更適合練板子 樹形dp更為簡單 說正解。注意到 p 2e 6 sum p le2e6 p 2 e6,這提示我們建一顆虛樹。建好後,2和3問就是求乙個樹上最短路,最長路,不再贅述。簡單說一下1,我們對於每一條邊統計有多少點對經過它。具體的,樹形dp的時候算出,即為...

P4103 HEOI2014 大工程 虛樹

戳這裡 虛樹板子題 首先有乙個 o qn 的暴力,就是對於每一次詢問,o n 的樹上 dp 我們統計一下每乙個點,它的子樹內離它最近 遠的關鍵點的距離,已經關鍵點的個數 對於第乙個詢問等價於 sum dep x dep y sum2 times dep lca 我們 dp 的時候順便統計一下每乙個點...

HEOI2014 大工程 虛樹 樹形DP

還不錯,就是理解題意的時候理解的久了一些。題目中的距離實際上是每兩個點在原樹上的距離,而新建的結點是不會影響的,所以總的距離和是原樹上任意兩點的距離之和 最短距離呢,實際上就是最短邊權了 最長距離,實際上就是新構成虛樹上樹的直徑了,當然得是有效點的。所以,構建虛樹,然後再進行乙個樹形dp就可以了。i...