標籤:單調佇列
description
小西有一條很長的彩帶,彩帶上掛著各式各樣的彩珠。已知彩珠有n個,分為k種。簡單的說,可以將彩帶考慮為x軸,每乙個彩珠有乙個對應的座標(即位置)。某些座標上可以沒有彩珠,但多個彩珠也可以出現在同乙個位置上。 小布生日快到了,於是小西打算剪一段彩帶送給小布。為了讓禮物彩帶足夠漂亮,小西希望這一段彩帶中能包含所有種類的彩珠。同時,為了方便,小西希望這段彩帶盡可能短,你能幫助小西計算這個最短的長度麼?彩帶的長度即為彩帶開始位置到結束位置的位置差。
input
第一行包含兩個整數n, k,分別表示彩珠的總數以及種類數。接下來k行,每行第乙個數為ti,表示第i種彩珠的數目。接下來按公升序給出ti個非負整數,為這ti個彩珠分別出現的位置。
output
應包含一行,為最短彩帶長度。
sample input
6 31 52 1 7
3 1 3 8
sample output
hint
有多種方案可選,其中比較短的是1~5和5~8。後者長度為3最短。
【資料規模】
對於50%的資料, n≤10000;
對於80%的資料, n≤800000;
對於100%的資料,1≤n≤1000000,1≤k≤60,0≤彩珠位置<2^31。
分析:用num陣列記錄每個彩珠出現的位置和種類,然後按照位置從小到大排序,從頭到尾掃一遍,類似於佇列的做法
注意:這題一定要把inf置為0x7fffffff,用0x3f3f3f會wa
code
#include#include#include#include#include#include#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#ifdef win32
#define ll "%i64d"
#else
#define ll "%lld"
#endif
using namespace std;
inline ll read()
while(ch>='0'&&ch<='9')
return x*f;
}const int maxn=1000006;
int inque[maxn],flag=0,ans=0x7fffffff,n,k,x,cnt=0,head,tail;
struct nodenum[maxn],que[maxn<<1];
inline bool cmp(node a,node b){return a.pos==b.pos?a.typeque[head].pos)head++;
if(!flag)check();
if(flag)ans=min(ans,que[tail].pos-que[head].pos);
//cout<
BZOJ 1293 SCOI2009 生日禮物
鏈結 我是鏈結,點我呀 題意 在這裡輸入題意 題解 顯然的滑動視窗題。尺取法 如果l.i這一段已經有k種珍珠了。那麼就嘗試把l 即把l這個影響嘗試去掉一下 如果不足k種珍珠了,那麼就把l 撤銷。否則l 照常 離散化一下資料 include define ll long long define rep...
BZOJ1293 SCOI2009 生日禮物
time limit 10 sec memory limit 162 mb submit 2590 solved 1424 submit status discuss 小西有一條很長的彩帶,彩帶上掛著各式各樣的彩珠。已知彩珠有n個,分為k種。簡單的說,可以將彩帶考慮為x軸,每乙個彩珠有乙個對應的座標...
BZOJ1293 SCOI2009 生日禮物
佇列 題目傳送門 這裡介紹一種尺取法。此處的尺意味游標卡尺 從左至右依次測量以當前點為右端點的區間 長度 那麼左端點呢?能用尺取法做的題必然滿足當右端點不斷往右移的時候,左端點不會往左移。所以我們每次就去 check 一下左端點是否能往右移,如果可以那就不斷地去 卡緊 測量範圍。對於這個題,用佇列表...