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

2021-06-10 01:16:22 字數 1623 閱讀 7271

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define iinf 1000000000

#define linf 1000000000000000000ll

#define dinf 1e200

#define all(v) (v).begin(),(v).end()

#define sz(x) x.size()

#define pb push_back

#define mp make_pair

#define lng long long

#define sqr(a) ((a)*(a))

#define pii pair#define pll pair#define pss pair#define pdd pair#define x first

#define y second

#define pi 3.14159265359

#define ff(i,xi,n) for(int i=xi;i<=(int)(n);++i)

#define ffd(i,xi,n) for(int i=xi;i>=(int)(n);--i)

#define ffl(i,r) for(int i=head[r];i!=-1;i=edge[i].next)

#define cc(i,j) memset(i,j,sizeof(i))

#define n 1000001

#define m 1000001

using namespace std;

typedef vectorvi;

typedef vectorvs;

typedef unsigned int uint;

typedef unsigned lng ulng;

templateinline void checkmax(t &x,t y)

templateinline t min(t x,t y)

templateinline t max(t x,t y)

}void dfs2(int r,int pre)

}int main()

dfs1(1,-1);edp[1]=0;dfs2(1,-1);

ff(i,1,n)

int ans=1;

q1[0]=0;q2[0]=0;r1=1;f1=1;r2=1;f2=1;q1[1]=1;q2[1]=1;int st=1;

ff(i,2,n)

else

if(wm) ++f1;

st=q1[f1-1]+1;

checkmax(ans,i-st+1);

while(f1<=r1&&edp[q1[r1]]<=w) --r1;

q1[++r1]=i;

while(f2<=r2&&edp[q2[r2]]>=w) --r2;

q2[++r2]=i;

}else

}printf("%d\n",ans);

}return 0;}/*

made by qinggege

*/

POJ 3162(樹形DP 單調佇列)

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

poj3162(樹形dp 線段樹)

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

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

題意 給一棵樹,求每個結點的樹上最遠距離,記為a i 然後求最大區間 l,r 滿足區間內的max a i min a i m。思路 第一步向hdoj2196那題一樣樹形dp求出每個結點的最長距離,我的另一篇部落格中有寫到求出最遠距離a i 後,建立線段樹維護區間的最大最小值。然後用兩個指標i,j遍歷...