bzoj2500 幸福的道路 樹形dp 單調佇列

2022-08-05 05:42:13 字數 1480 閱讀 9684

小t與小l終於決定走在一起,他們不想浪費在一起的每一分每一秒,所以他們決定每天早上一同晨練來享受在一起的時光.

他們畫出了晨練路線的草圖,眼尖的小t發現可以用樹來描繪這個草圖.

他們不願枯燥的每天從同乙個地方開始他們的鍛鍊,所以他們準備給起點標號後順序地從每個起點開始(第一天從起點一開始,第二天從起點二開始……). 而且他們給每條道路定上乙個幸福的值.很顯然他們每次出發都想走幸福值和最長的路線(即從起點到樹上的某一點路徑中最長的一條).

他們不願再經歷之前的大起大落,所以決定連續幾天的幸福值波動不能超過m(即一段連續的區間並且區間的最大值最小值之差不超過m).他們想知道要是這樣的話他們最多能連續鍛鍊多少天(hint:不一定從第一天一直開始連續鍛鍊)?

現在,他們把這個艱鉅的任務交給你了!

第一行包含兩個整數n, m(m<=10^9).

第二至第n行,每行兩個數字fi , di, 第i行表示第i個節點的父親是fi,且道路的幸福值是di.

最長的連續鍛鍊天數

3 21 1

1 33

資料範圍:

50%的資料n<=1000

80%的資料n<=100 000

100%的資料n<=1000 000

第一問,每個點能到達的最長鏈無非就是要麼往子樹走,要麼往父親走再往上走,那麼我們用\(u[i]\)和\(d[i]\)分別表示向上走和向下走的最長鏈,向下走的直接dfs即可,向上走的我們更新x的兒子的dp值的時候,我們記錄x兒子中\(d[i]\)的最大值和次大值,如果這個兒子不是最大值,那麼用最大值更新,否則用次大值更新。記得x兒子的初值是\(u[x]\)。

第二問我們開倆單調佇列,維護遞減的最大值和遞增的最小值,加入乙個元素的時候按照正常操作更新佇列,之後我們要從隊首彈出元素直到兩者之差小於等於m,彈出佇列的過程就是哪邊更靠左,就把哪邊彈出,然後維護乙個pos表示答案能夠延伸到的左端點,每次彈出的時候更新為\(q[l1/l2]+1\)。這樣經過若干次迭代之後就能找到合法的最靠左的pos,然後用\(i-pos+1\)更新答案。

當然這題的範圍是允許st表的,偷懶寫st表也可以(模擬賽記憶體砍了一半所以寫不了qwq)

#include #define ll long long

using namespace std;

struct nod};

vectore[1000005];

int n,x,q1[1000005],q2[1000005],l1=1,l2=1,r1,r2,g=1,ans;

ll m,y,u[1000005],d[1000005],a[1000005];

void dfs1(int x,int f)

for(int i=0,t;i=a[q2[r2]]) r2--;

q1[++r1]=i;q2[++r2]=i;

while(a[q2[l2]]-a[q1[l1]]>m) if(q2[l2]ans=max(ans,i-g+1);

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

}

bzoj 2500 幸福的道路

link 幸福的道路 題目有坑.題意 一棵樹 求出每個點到樹上另外乙個點的最大距離 在距離陣列上求出最長一段連續的區間使其極差 s 求區間長度最大值。題目說的標號的意思就是指樹上的標號 而不是重新的標號。求樹上某個點到另外乙個點的最大值 沒有什麼好的辦法 通常都是樹形dp 換根 換根比較基礎再維護乙...

bzoj2500幸福的道路 樹形dp 單調佇列

time limit 20 sec memory limit 256 mb submit 434 solved 170 submit status discuss 小t與小l終於決定走在一起,他們不想浪費在一起的每一分每一秒,所以他們決定每天早上一同晨練來享受在一起的時光.他們畫出了晨練路線的草圖,...

bzoj 2500 幸福的道路 動態規劃 單調棧

題意 給出一棵樹,每條邊都有乙個長度。我們規定每個點的權值為從該點開始走過的一條最長的路徑的長度。求乙個最長的區間 l,r 使得 l,r 裡面點權的最大值和最小值只差不超過m。n 1000000 一開始看錯題目了,結果卡了半天。最後發現是一道大水題。先求點權,直接dp求,經典模型啊。隨便寫。後面求出...