小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求,經典模型啊。隨便寫。後面求出...