luogu P1712區間 題解

2022-09-08 07:21:08 字數 2294 閱讀 2249

【noi2016】區間

在數軸上有nn 個閉區間 [l_1,r_1],[l_2,r_2],...,[l_n,r_n][l1​,r1​],[l2​,r2​],...,[ln​,rn​] 。現在要從中選出mm個區間,使得這mm 個區間共同包含至少乙個位置。換句話說,就是使得存在乙個 xx ,使得對於每乙個被選中的區間[l_i,r_i][li​,ri​] ,都有 l_i≤x≤r_ili​≤x≤ri​。

對於乙個合法的選取方案,它的花費為被選中的最長區間長度減去被選中的最短區間長度。區間[l_i,r_i][li​,ri​] 的長度定義為r_i-l_iri​−li​,即等於它的右端點的值減去左端點的值。

求所有合法方案中最小的花費。如果不存在合法的方案,輸出-1−1 。

第一行包含兩個正整數n,mn,m 用空格隔開,意義如上文所述。保證1≤m≤n1≤m≤n

接下來nn 行,每行表示乙個區間,包含用空格隔開的兩個整數l_ili​和r_iri​為該區間的左右端點。

n<=500000,m<=200000,0≤li≤ri≤10^9n<=500000,m<=200000,0≤li≤ri≤109

只有一行,包含乙個正整數,即最小花費。

輸入

6 3

3 51 2

3 42 2

1 51 4

輸出

2

這道題呢,題目說要用長度最大的區間減去長度最小的區間,正好本來序列就沒什麼順序,那我們給區間排個序吧,這樣可以方便統計答案。

排完序做什麼呢?一定是統計每個點出現的次數吧。對於這些個區間,修改區間上點出現的次數,線段樹是常規操作吧。

我們用線段樹修改所有點出現的次數的最大值,這樣,當列舉到i時,加上區間i對點出現次數的貢獻,此時tree[1]如果等於m,這說明乙個可能的答案產生了。

我們列舉剛剛統計過的區間j,把他的貢獻刪掉,線段樹區間減。

看看tree[1]是否發生變化。

如果tree[1]變小,那說明這是對這個答案有影響的長度最小的區間了。更新答案ans=min(ans,sec[i].len-sec[j].len)。

想想為什麼可以刪掉j這個區間?因為i後面的區間一定比i長,減去j後產生的答案一定會更大,因此完全不用考慮j對i後面區間的影響。

既然j被刪掉了,那麼下乙個區間就是j+1了,用head標記這個,當下乙個答案產生時,從head開始列舉。

注意到原區間座標很大,引入離散化是必要的。

#include#include

#include

#include

#define ls k<<1

#define rs k<<1|1

#define min(x,y) (x#define max(x,y) (x>y?x:y)

using

namespace

std;

const

int n=550000

; int n,m,ans=0x7fffffff

;int temp[n<<4

];int tree[n<<4],tag[n<<4

];struct

nodesec[n];

inline

bool

cmp(node x,node y)

inline

void read(int &x)

inline

void updata(int k,int x,int

y)inline

void change(int k,int x,int y,int l,int r,int

val)

if(tag[k]) updata(k,x,y);

int mid=x+y>>1

; change(ls,x,mid,l,r,val);

change(rs,mid+1

,y,l,r,val);

tree[k]=max(tree[ls],tree[rs]);

}int

main()

sort(sec+1,sec+n+1

,cmp);

sort(temp+1,temp+1+cnt);

cnt=unique(temp+1,temp+1+cnt)-temp-1

;

for(i=1;i<=n;i++)

int head=0

;

for(i=1;i<=n;i++)}}

if(ans==0x7fffffff) ans=-1

;//不要忘記判斷這個。

printf("%d

",ans);

}

題解 P1712 NOI2016 區間

先按照長度排個序,然後依次新增區間。什麼是新增?設這個區間是 l r l,r 新增就是把al al 1,al 2,a r al,al 1 al 2,ar 都加上1 1 其中ai role presentation style position relative aia i表示第 i i 個位置被幾個...

51nod 1712 區間求和

解法 這個題首先考慮乙個簡單情況 對於區間 x,y 權值為多少。容易寫出公式 f x y s y s x 1 sum y sum x 1 x 1 sum x 1 y x 1 其中s x 表示 從第乙個元素到第x個元素的 所有有序二元組的和 題目中定義的 sum表示字首和 這裡要求的是所有a x a ...

洛谷 P1712 區間

在數軸上有 n個閉區間 l1,r1 l2,r2 ln,rn 現在要從中選出 m 個區間,使得這 m個區間共同包含至少乙個位置。換句話說,就是使得存在乙個 x,使得對於每乙個被選中的區間 li,ri 都有 li x ri。對於乙個合法的選取方案,它的花費為被選中的最長區間長度減去被選中的最短區間長度。...