題目鏈結
題目大意:給定$n$個區間$[l_i,r_i]$,選出$m$個區間使它們有乙個共同的位置$x$,且使它們產生的費用最小。求最小費用。費用定義為最長的區間長度減去最短區間長度。
因為區間順序改動又不影響答案,我們不妨按照長度排個序。看到資料範圍果斷離散化。
思考一種最樸素的做法:將排好序的區間逐一加入數軸,看有沒有乙個點被覆蓋的次數$\geq m$。
有的話就統計一下答案,然後將前面加入的數刪掉,直到$顯然用到了尺取法。維護是否有乙個點被覆蓋的次數可以用線段樹。
然後就可以成功a掉此題。
**:
#includeusingnamespace
std;
int n,m,maxx,b[1000005],cnt,size,head=0,tail=0,ans=0x3f3f3f3f
;struct
node
a[500005
];struct
tree
tree[
4000005
];inline
intread()
while(isdigit(ch))
return x*f;
}bool
cmp(node x,node y)
inline
void build(int index,int l,int
r)inline
void pushdown(int
index)
inline
void update(int index,int l,int r,int
x)
if(tree[index].lazy) pushdown(index);
int mid=(tree[index].l+tree[index].r)>>1
;
if (l<=mid) update(index*2
,l,r,x);
if (r>mid) update(index*2+1
,l,r,x);
tree[index].max=max(tree[index*2+1].max,tree[index*2
].max);
}int
main()
sort(b+1,b+cnt+1
); size=unique(b+1,b+cnt+1)-b-1
; sort(a+1,a+n+1
,cmp);
for (int i=1;i<=n;i++)
build(
1,1,maxx);
while(tailif (tree[1].maxbreak
;
while(head<=tail&&tree[1].max>=m)
}if (ans==0x3f3f3f3f) printf("-1"
);
else printf("%d"
,ans);
return0;
}
線段樹 NOI2016 區間
在數軸上有 n 個閉區間 l 1,r1 l 2,r2 l n,rn 現在要從中選出 m 個區間,使得這 m個區間共同包含至少乙個位置。換句話說,就是使得存在乙個 x 使得對於每乙個被選中的區間 l i,ri 都有 li x r i 對於乙個合法的選取方案,它的花費為被選中的最長區間長度減去被選中的最...
NOI2016 區間 線段樹
在數軸上有 n個閉區間 l1,r1 l2,r2 ln,rn 現在要從中選出 m 個區間,使得這 m個區間共同包含至少乙個位置。換句話說,就是使得存在乙個 x,使得對於每乙個被選中的區間 li,ri 都有 li x ri。對於乙個合法的選取方案,它的花費為被選中的最長區間長度減去被選中的最短區間長度。...
NOI2016 區間 線段樹
將區間按照長度排序,每次將相同長度的區間插入,直到有乙個點能被至少m個區間覆蓋,這個可以用線段樹維護。這時我們就可以刪除長度小的區間直到不滿足條件。重複做就可以了 1 include 2 include 3 include 4 include 5 include 6 define ll long l...