貪心 堆 樹狀陣列 JXOI2017 加法 題解

2021-08-06 05:22:40 字數 1421 閱讀 9419

有乙個序列

和 m 個區間,你可以選

k個區間,選擇區間 [l

,r] 可以使

a 中的 [l

,r]都加上

a ,找出乙個方案使得

a中最小值最大。

由於是求最小值的最大值,所以我們想到二分答案 mi

d ,這樣我們就知道序列中每個數還需要加多少次才能 ≥

mid ,設第

i 個數的次數為 ti

[i]。

那麼接下來我們要做的就是驗證是否能用 ≤k

​ 個線段覆蓋掉 ti

​ 陣列,這個可以用貪心解決:從左往右列舉 i​

,對於 i​

我們需要 ti

[i]​

個滿足條件的線段來覆蓋,什麼樣的線段比較優秀呢?肯定是右端點遠的線段!所以我們用堆維護這些滿足條件的線段,每次從中選出右端點最遠的線段使用,並將 ti

​ 陣列進行相應的修改(這個可以用樹狀陣列解決)。如果使用的線段數量 ≤k

​ 就說明驗證成功。

2017.8.15update:由於**有些小技巧,加了點注釋。

#include

#include

using

namespace

std;

#define fir first

#define sec second

const

int maxn=200000,maxm=200000;

int te,n,m,k,a,a[maxn+5];

pair s[maxm+5];

inline

bool eoln(char ch)

inline

char readc()

inline

int readi(int &x)

if (lst=='-') f=-f;

while ('0'

<=ch&&ch<='9') tot=(tot<<3)+(tot<<1)+ch-48,ch=readc();

return x=tot*f,eoln(ch);

}int c[maxn+5];

void update(int x,int tem)

int sum(int x)

int si,heap[maxn+5];

bool check(int min)

//pop_heap同理

if (ti) return

false;

}return

true;

}int main()

sort(s+1,s+1+m);r+=a*k;

while (l<=r)

printf("%d\n",l-1);

}return

0;}

JXOI2017 加法題解

1 首先要想到貪心,若想要滿足最小數最大,那麼我們盡量選區間長度長的修改方法修改,這樣同是加a,但是長度長的加的更多,明顯比較優越。2 如何找到最大區間,我們可以在輸入後對其左端點排序 原因等會說 令最小的左端點排在前面,然後要用時再依次插入優先佇列,而優先佇列即是要用來將左端點滿足條件且最大區間排...

解題報告 JXOI2017 數列 DP

給定乙個長度為 n 的整數數列 構造數列 滿足以下條件 求滿足上述條件的數列 的數量.n le 50,r i le 150 計數題,考慮 dp 設 f i l r 為 考慮到 a i l 為 a 中小於等於 a i 的最大值,r 為 a 中大於等於 a i 的最小值時,數列 的數量.首先明確一點,當...

JXOI2017 顏色 線段樹求點對貢獻

可憐有乙個長度為 n 的正整數序列 ai,其中相同的正整數代表著相同的顏色。現在可憐覺得這個序列太長了,於是她決定選擇一些顏色把這些顏色的所有位置都刪去。刪除顏色 i 可以定義為把所有滿足 aj i 的位置 j 都從序列中刪去。然而有些時候刪去之後,整個序列變成了好幾段,可憐不喜歡這樣,於是她想要知...