CCPC.2017哈爾濱站-重現賽-B(二分)
阿新 • • 發佈:2019-02-05
題意:給你一個序列,讓你將所有子串中第k大的數拿出來,排成一排,求生成序列第m大的數是多少?
題解:比賽時想的是單調棧的方法,哇,搞了快兩個小時,思路一開始就是錯的。。。。真的是。。。
正解是二分答案,很容易想到對於第m大的數的取值是存在單調性的。想到二分答案問題基本上就解決了,
剩下的就是判斷答案的合法性,我們可以每次列舉所有子串的起點,然後定義指標p往後遍歷直到以p結尾的
子區間中大於等於當前答案的數有k個時,呢麼以i為起點的合法區間就有n-p+1個,這個很容易明白,因為
p後邊的數假如比當前列舉的答案小,呢麼一定不會影響答案(別忘了是求第k大),假如比當前列舉的答案大的話,呢一定是生成序列中排在
#include<stdio.h> int a[100005],n,k; long long m; long long check(int x) { int sum=0,p=0; long long res=0; for(int i=1;i<=n;i++) { while(sum<k && p<=n) { if(a[++p]>=x) sum++; } res+=n-p+1; if(a[i]>=x) sum--; } return res; } int main(void) { int T; scanf("%d",&T); while(T--) { int ans; scanf("%d%d%lld",&n,&k,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int l=1,r=1000000001; while(l<=r) { int mid=(l+r)/2; if(check(mid)>=m) ans=mid,l=mid+1; else r=mid-1; } printf("%d\n",ans); } return 0; }