第k大区间
定义一个区间的值为其众数出现的次数。
现给出n个数,求将所有区间的值排序后,第K大的值为多少。
Input
第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 第二行n个数,0<=每个数<2^31
Output
一个数表示答案。
Input示例
4 2 1 2 3 2
Output示例
2
题解:
二分答案,
我们假设x,计算出多少个区间的众数大于等于K就好了
方法就是:枚举一个区间的右端点,那么我们假设找到一个左端点尽量大,那么就是固定的右端点的答案,累加就是了
注意这题不要用map等STL,会超时
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include<vector> using namespace std; const int N = 1e5+10, M = 30005, mod = 1e9+7, inf = 0x3f3f3f3f; typedef long long ll; //不同为1,相同为0 void read(ll &x){ char ch=getchar();x=0; for (;ch<'0';ch=getchar()); for (;ch>='0';ch=getchar()) x=x*10+ch-'0'; } vector<int> G[N]; int H[N]; ll n,k,a[N],pos[N],b[N]; ll cal(int x) { if(x==1) return n*(n-1)/2; ll ans = 0,L = 0; for(int i=1;i<=n;i++) G[i].clear(); memset(H,0,sizeof(H)); for(int i=1;i<=n;i++) { if(H[a[i]]>=x-1) { pos[i] = G[a[i]][H[a[i]]+1 - x]; } else pos[i] = 0; L = max(L,pos[i]); ans+=L; H[a[i]]++; int tmp = H[a[i]]; G[a[i]].push_back(i); } // cout<<pos[n]<<endl; //cout<<ans<<endl; return ans; } int main() { read(n),read(k); for(int i=1;i<=n;i++) read(a[i]), b[i] = a[i]; sort(b+1,b+n+1); int c = unique(b+1,b+n+1)-b-1; for(int i=1;i<=n;i++) a[i] = lower_bound(b+1,b+c+1,a[i]) - b; // cout<<cal(2)<<endl; int l = 1, r = n; ll ans = 1; while(l<=r) { int mid = (l+r)>>1; if(cal(mid)>=k) l = mid+1, ans = mid; else r = mid-1; } printf("%lld\n",ans); //cout<<ans<<endl; return 0; }