NOI2016 區間 題解

2022-07-13 20:15:13 字數 1465 閱讀 8494

題目大意:

有n個區間,當有m個區間有公共部分時,求m個區間長度的最大值與最小值之差的最小值。

思路:

按區間的長度從小到大排序,可知連續的幾個區間最優,則用兩個指標指其頭尾,線性掃瞄,再用線段樹區間覆蓋。

**:

1 #include2 #include3 #include4

#define n 1000009

5#define inf 2147483647

6using

namespace

std;78

int n,m,i,j,cnt,ans=inf,sum[n<<2],lazy[n<<2],b[n<<1];9

struct node a[n];

1011

bool cmp(const node &x,const node &y)

1215

16int find(int l,int r,int

x)17

2324

void up_date(int k,int

x)25

2829

void change(int cur,int l,int r,int l,int r,int

val)

3032

int mid=l+r>>1;33

if(lazy[cur])

3439

if (r<=mid) change(cur<<1

,l,mid,l,r,val);

40else

if (l>mid) change(cur<<1|1,mid+1

,r,l,r,val);

41else change(cur<<1,l,mid,l,mid,val),change(cur<<1|1,mid+1,r,mid+1

,r,val);

42 sum[cur]=max(sum[cur<<1],sum[cur<<1|1

]);43}44

45void

solve()

4654 ans=min(ans,a[j].len-a[i].len);

55 change(1,1,cnt,a[i].l,a[i].r,-1

);56}57

}5859int

main()

6068 sort(a+1,a+n+1,cmp),sort(b+1,b+cnt+1

);69

for (i=1;i<=n;i++) a[i].l=find(1,cnt,a[i].l),a[i].r=find(1

,cnt,a[i].r);

70 solve(); printf("

%d\n

",ans1

);71

return0;

72 }

題解 NOI2016區間

two pointer 第一題 大概就是對於一段連續的區間求解,使用兩個指標不斷卡區間的長度直到區間不滿足條件吧。這題只要對區間以長度從小到大排一下序,然後使用兩個指標指向區間。線段樹維護被覆蓋最多次數的節點被覆蓋了多少次。如果滿足條件,由於我們是在第一次判斷的時候發現它滿足條件的,所以最後加入的這...

線段樹 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。對於乙個合法的選取方案,它的花費為被選中的最長區間長度減去被選中的最短區間長度。...