noip模擬賽 第k大區間

2022-05-01 09:12:15 字數 1682 閱讀 9888

【問題描述】

定義乙個長度為奇數的區間的值為其所包含的的元素的中位數。

現給出n個數,求將所有長度為奇數的區間的值排序後,第k大的值為多少。

【輸入】

輸入檔名為kth.in。

第一行兩個數n和k

第二行,n個數。(0<=每個數<231)

【輸出】

輸出檔名為kth.out。

乙個數表示答案。 

【輸入輸出樣例】

kth.in

kth.out

4 33 1 2 4

【樣例解釋】

[l,r]表示區間l~r的值

[1,1]:3

[2,2]:1

[3,3]:2

[4,4]:4

[1,3]:2

[2,4]:2

【資料說明】

對於30%的資料,1<=n<=100;

對於60%的資料,1<=n<=300

對於80%的資料,1<=n<=1000

對於100%的資料,1<=n<=100000, k<=奇數區間的數 

分析:有點難想的一道題.

看到第k大,就應該想到要二分.二分x,接下來的任務就是找有多少個區間的值》=x.既然是中位數》=x,那麼比x大的數在區間中肯定佔了一半以上的數量,那麼開乙個陣列sum[i]表示1~i中有多少個數》=x.乙個區間只有2*(sum[r] - sum[l - 1]) > r - (l - 1).接下來就是常見的套路了,把結構相同的放在一起:2*sum[r] - r > 2*sum[l - 1] - (l - 1),換個元,另b[i] = 2*sum[i] - i,問題就轉化成了有多少個j滿足j < i && b[j] < b[i],樹狀陣列維護一遍就可以了.由於區間長度為奇數,所以要開兩個樹狀陣列分別記錄奇數和偶數的答案.

第k小/大用二分,式子一定要變形,相同結構放一起,換元之後再求解.

#include #include 

#include

#include

using

namespace

std;

typedef

long

long

ll;ll n, k, a[

100010], b[100010], l, r, ans, c[2][300010

];long

long

anss;

long

long

query(ll x, ll id)

return

res;

}void

add(ll x, ll id)

}ll cal(ll p)

for (int i = 0; i <= n; i++)

b[i] = 2 * b[i] - i + 100010

; anss = 0

;

for (int i = 0; i <= n; i++)

return

anss;

}int

main()

l = 0

;

while (l <=r)

else

r = mid - 1

; }

printf(

"%lld\n

", ans);

return0;

}

noip模擬賽 第K小數

問題描述 有兩個正整數數列,元素個數分別為n和m。從兩個數列中分別任取乙個數 相乘,這樣一共可以得到n m個數,詢問這n m個數中第k小數是多少。輸入格式 輸入檔名為number.in。輸入檔案包含三行。第一行為三個正整數n,m和k。第二行為n個正整數,表示第乙個數列。第三行為m個正整數,表述第二個...

51Nod 1686 第K大區間

題意 中文題,定義乙個區間的值為其眾數出現的次數。現給出n個數,求將所有區間的值排序後,第k大的值為多少。離散化二分答案加尺取判斷 include include includeusing namespace std const int maxn 100006 typedef long long l...

51nod 1686 第K大區間

1686 第k大區間 基準時間限制 1 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 定義乙個區間的值為其眾數出現的次數。現給出n個數,求將所有區間的值排序後,第k大的值為多少。input 第一行兩個數n和k 1 n 100000,k n n 1 2 第二行n個數,0 每個數 2...