基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
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 ,那么,区间无论怎么左右扩展,区间的值必然大于等于 x 。
那么,计算区间的值大于等于 x ,可以用尺取在 O(n) 时间算出,显然,这是有单调性的,二分即可
1 # include <cstdio> 2 # include <cstring> 3 # include <cstdlib> 4 # include <iostream> 5 # include <vector> 6 # include <queue> 7 # include <stack> 8 # include <map> 9 # include <bitset> 10 # include <sstream> 11 # include <set> 12 # include <cmath> 13 # include <algorithm> 14 # pragma comment(linker,"/STACK:102400000,102400000") 15 using namespace std; 16 # define LL long long 17 # define pr pair 18 # define mkp make_pair 19 # define lowbit(x) ((x)&(-x)) 20 # define PI acos(-1.0) 21 # define INF 0x3f3f3f3f3f3f3f3f 22 # define eps 1e-8 23 # define MOD 1000000007 24 25 inline int scan() { 26 int x=0,f=1; char ch=getchar(); 27 while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} 28 while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} 29 return x*f; 30 } 31 inline void Out(int a) { 32 if(a<0) {putchar('-'); a=-a;} 33 if(a>=10) Out(a/10); 34 putchar(a%10+'0'); 35 } 36 # define MX 100005 37 /**************************/ 38 39 int n,k; 40 int a[MX]; 41 int b[MX]; 42 int num[MX]; 43 44 bool check(int x) 45 { 46 memset(num,0,sizeof(num)); 47 int l=1,r=1,flag=0; 48 LL tot=0; 49 while (r<=n+1) 50 { 51 if (!flag) 52 { 53 if (r==n+1) break; 54 num[a[r]]++; 55 if (num[a[r]]>=x) flag=r; 56 r++; 57 } 58 else 59 { 60 while (flag) 61 { 62 tot += n-r+2; 63 num[a[l]]--; 64 if (num[a[flag]]<x) flag=0; 65 l++; 66 } 67 } 68 } 69 if (tot>=k) return 1; 70 return 0; 71 } 72 73 int main() 74 { 75 scanf("%d%d",&n,&k); 76 for (int i=1;i<=n;i++) 77 { 78 scanf("%d",&a[i]); 79 b[i] = a[i]; 80 } 81 sort(b+1,b+1+n); 82 for (int i=1;i<=n;i++) 83 a[i] = lower_bound(b+1,b+1+n,a[i])-b; 84 85 int l=1, r=n; 86 int ans; 87 while (l<=r) 88 { 89 int mid = (l+r)>>1; 90 if (check(mid)) ans=mid,l=mid+1; 91 else r=mid-1; 92 } 93 printf("%d ",ans); 94 return 0; 95 }