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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P5904-[POI2014]HOT-Hotels加强版【长链剖分,dp】

發(fā)布時間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P5904-[POI2014]HOT-Hotels加强版【长链剖分,dp】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P5904


題目大意

nnn個點的一棵樹,求有多少個點對(i,j,k)(i,j,k)(i,j,k)使得這三個點距離相等。


解題思路

有兩種情況,一是iiij,kj,kj,k的祖先,二是i,j,ki,j,ki,j,k互相沒有祖先關系

考慮dpdpdpfi,jf_{i,j}fi,j?表示iii點的子樹中與iii距離為jjj的點的個數(shù),然后gi,jg_{i,j}gi,j?表示iii的子樹中滿足有多少個點(x,y)(x,y)(x,y)對使得dis(x,lca)=dis(y,lca)=dis(i,lca)+jdis(x,lca)=dis(y,lca)=dis(i,lca)+jdis(x,lca)=dis(y,lca)=dis(i,lca)+j。然后考慮統(tǒng)計答案
ans+=gy,i?fx,i?1+gx,i+1?fy,ians+=g_{y,i}*f_{x,i-1}+g_{x,i+1}*f_{y,i}ans+=gy,i??fx,i?1?+gx,i+1??fy,i?
然后考慮這個點對ggg的影響有
gx,i+1+=fx,i+1?fy,ig_{x,i+1}+=f_{x,i+1}*f_{y,i}gx,i+1?+=fx,i+1??fy,i?
然后繼承gx,i?1+=gy,i,fx,i+1+=fy,ig_{x,i-1}+=g_{y,i},f_{x,i+1}+=f_{y,i}gx,i?1?+=gy,i?,fx,i+1?+=fy,i?

然后可以長鏈剖分進行優(yōu)化,fff在長鏈上向后運動,但是ggg是向前運動的。

考慮結點111,因為每次向前運動要放在len1len_1len1?的位置,但是該位置向后又要儲存len1len_1len1?個值,所以我們要開兩倍的空間

時間復雜度O(n)O(n)O(n)


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=4e5+10; struct node{ll to,next; }a[N*2]; ll n,tot,ans,ls[N],son[N]; ll len[N],buff[N*2],bufg[N*2]; ll *f[N*2],*g[N*2],*nowf,*nowg; void addl(ll x,ll y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return; } void dfs(ll x,ll fa){for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;dfs(y,x);if(len[y]>len[son[x]])son[x]=y;}len[x]=len[son[x]]+1;return; } void solve(ll x,ll fa){f[x][0]=1;if(son[x]){f[son[x]]=f[x]+1;g[son[x]]=g[x]-1;solve(son[x],x);}ans+=g[x][0];for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==son[x]||y==fa)continue;f[y]=nowf;nowf+=len[y];nowg+=len[y]*2+10;g[y]=nowg++;solve(y,x);for(ll j=0;j<len[y];j++){if(j)ans+=g[y][j]*f[x][j-1];ans+=g[x][j+1]*f[y][j];}for(ll j=0;j<len[y];j++){g[x][j+1]+=f[y][j]*f[x][j+1];if(j)g[x][j-1]+=g[y][j];f[x][j+1]+=f[y][j];}}return; } int main() {scanf("%lld",&n);for(ll i=1;i<n;i++){ll x,y;scanf("%lld%lld",&x,&y);addl(x,y);addl(y,x);}dfs(1,1);nowf=buff;nowg=bufg;nowf+=len[1];nowg+=len[1]*2+10;f[1]=buff;g[1]=nowg++;solve(1,1);printf("%lld",ans); }

總結

以上是生活随笔為你收集整理的P5904-[POI2014]HOT-Hotels加强版【长链剖分,dp】的全部內容,希望文章能夠幫你解決所遇到的問題。

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