平均數 題解 二分 求逆序對

2021-07-24 15:32:55 字數 1372 閱讀 8457

有一天,小a得到了乙個長度為n的序列。他把這個序列的所有連續子串行都列了出來,並對每乙個子串行都求了其平均值,然後他把這些平均值寫在紙上,並對它們進行排序,最後他報出了第k小的平均值。你要做的就是模仿他的過程。

第一行兩個整數n,k,意義如題中所述。

第二行n個正整數,即為小a得到的序列。

一行乙個實數,表示第k小的平均值,保留到小數點後4位。

對於40%的資料,n≤1000

對於100%的資料,n≤100000,k≤n*(n+1)/2,序列中的數≤10^9

第k大不易直接求,我們想到二分,則原問題轉變為求區間平均值小於x的區間數量。考慮把序列中的每個數減去x,則我們只需求區間和小於0的區間數量。我們對這個序列求字首和,則區間[l,r]和小於0當且僅當sl-1>sr,答案即為字首和序列s的逆序對數量,使用經典的歸併排序即可解決,時間複雜度o(nlog^2n)。

對於精度問題,可以把資料*100000,最後再除以100000.0即可

#include

#include

#include

#include

#include

#define ll long long

using

namespace

std;

const

int maxn=100005;

ll n,m,num,mina,maxa;

ll a[maxn],s[maxn],c[maxn];

ll merge(int l,int mid,int r)

else

}while (i<=mid) tmp[k++]=s[i++];

while (j<=r) tmp[k++]=s[j++];

for (int i=l;i<=r;i++) s[i]=tmp[i];

return sum;

}ll mergesort(int l,int r)

return tmp;

}ll work(ll p)

int main()

ll mid,l=mina,r=maxa;

while (l+1

//l+1else

l=mid;

}double ans=r*1.0/100000;

printf("%.4lf\n",ans);

return

0;}

有單調性考慮二分

轉換思想(如第k大轉換為比x小的有多少,同減平均數,區間<0則找逆序對)

求第k大轉換為列舉某個數,比它小的有多少個

二分判斷為l+1

聯賽模擬測試5 平均數 二分答案 逆序對

之前做過類似的兩道題,一道是區間和的 k 小值,一道是眾數的 k 小值 那兩道統計的東西都有單調性,可以用兩個指標維護,o n 計算 但是平均數沒有單調性,不能用兩個指標去掃 但是這道題的資料範圍是 10 5 時間限制是 2.5s 統計答案時還可以再套乙個 log 如果當前列舉的平均值是 mid 的...

P1404 平均數 二分

p1404 平均數 二分 這是乙個很常見的二分題目可能題目正解不是二分是單調佇列,而這題呢 我之前一直被幾組陣列卡到懷疑人生,01數規劃嘛就是讓a i mid,然後加起來如果 0那麼就滿足條件,然後我就想著長度為m的一定是最大的,但是資料教我做人,等下看 就知道了。include include i...

JZOJ4256 平均數 二分

給出包含乙個n n個整數的陣列a a。找出一段長度至少為m m的連續序列,最大化它的平均值。很明顯這道題的答案滿足單調性。若可以找出一段區間的平均值超過k k,那麼必然可以找到一段區間的平均值超過k 1 k 1。那麼可以考慮二分答案。設二分的答案為ans ans若 ij a i j i ans j ...