poj3162(樹形dp 線段樹求最大最小值)

2022-08-21 18:24:13 字數 1585 閱讀 7097

題意:給一棵樹,求每個結點的樹上最遠距離,記為a[i],然後求最大區間[l,r]滿足區間內的max(a[i])-min(a[i])<=m。

思路:第一步向hdoj2196那題一樣樹形dp求出每個結點的最長距離,我的另一篇部落格中有寫到求出最遠距離a[i]後,建立線段樹維護區間的最大最小值。然後用兩個指標i,j遍歷一遍,每次求出[i,j]的最大最小值ans1和ans2,更新答案,因為j每次不用初始化,總複雜度為o(nlogn)。

ac**:

#include#include

using

namespace

std;

typedef

long

long

ll;const

int maxn=1e6+5

;const ll inf=0x3f3f3f3f3f3f3f3f

;int

n,ans,cnt,head[maxn],pt[maxn],a[maxn];

ll m,dp[maxn][

3],ans1,ans2;

struct

node1edge[maxn

<<1

];struct

node2tr[maxn

<<2

];void adde(int u,int

v,ll w)

void dfs1(int u,int

fa)

else

if(w+dp[v][0]>dp[u][1

]) dp[u][

1]=w+dp[v][0

]; }

}void dfs2(int u,int

fa)}

void pushup(int

v)void build(int v,int l,int

r)

int mid=(l+r)>>1

; build(v

<<1

,l,mid);

build(v

<<1|1,mid+1

,r);

pushup(v);

}void query(int v,int l,int

r)

int mid=(tr[v].l+tr[v].r)>>1

;

if(l<=mid) query(v<<1

,l,r);

if(r>mid) query(v<<1|1

,l,r);

}int

main()

dfs1(

1,0);

dfs2(

1,0);

for(int i=1;i<=n;++i)

a[i]=max(dp[i][0],dp[i][2

]); build(

1,1,n);

int j=1

;

for(int i=1;i<=n;++i)

ans=max(ans,j-i);

}printf(

"%d\n

",ans);

return0;

}

poj3162(樹形dp 線段樹)

題意 n個結點構成一棵樹 mc將在n天,依次按結點編號設為起點,選取距離起點最遠的結點作為終點,得到最遠距離。問 找到乙個區間,使得這個區間裡最大最小值的差距不超過m,求區間的最大長度。解題思路 求每天的最遠距離很明顯是樹形dp的問題,求的n個值後,我們可以用線段樹來儲存這些值。每次維護區間的l,r...

POJ 3162(樹形DP 單調佇列)

題意 求1 n 在樹上的最遠距離d i 1 i n 然後求出d陣列裡最長區間長度且滿足區間最大值 最小值 m 思路 樹形dp求出陣列d 然後兩個單調佇列分別維護最小值最大值,並且維護乙個最左端點l,更新佇列 端點和答案即可。ac include include include include usi...

poj 3162 樹形dp 單調佇列 很好的題

include include include include include include include include include include include include include include define iinf 1000000000 define linf 100...