牛客网 The K-th Largest Interval (二分+尺取)

链接:https://www.nowcoder.com/acm/contest/102/C
来源:牛客网

 We define a value of an interval is the second largest number of it's elements, and of course an interval has at least two elements.      Given an array A with n elements and a number k, can you find the value of the kth largest interval?    
输入描述:
The first line contains an integer number T, the number of test cases. For each test case : The first line contains two integer numbers n,k(2 ≤ n ≤ 105,1 ≤ k ≤ n(n−1)/2), the number of test cases. The second lines contains n integers Ai(1 ≤ Ai ≤ 109), the elements of array A.
输出描述:
For each test case print the value of the kth largest interval.

示例1

输入

2
3 3
1 2 3
5 1
1 2 2 3 3

输出

1
3

说明

For the sample input, there are three intervals.Interval [1 2 3] has value 2.Interval [2 3] has value 2.Interval [1 2] has value 1.So the 3rd largest interval is [1 2] whose value is 1.

题意: 设定一个区间的次小值,作为这个区间的权值,问所有的区间中,第k大的权值是多少?

分析:如果一个数是第k大的权值,就说明权值大于等于它的区间至少有k个。

           枚举这样的一个数的时候,它的大小,和比它大的权值的数量呈线性关系,所以可以采用二分

           当目前求大于等于x的权值个数的时候,区间包含两个大于等于x的数的时候才会产生贡献。

           再通过尺取,求出不重复的贡献值总和。

代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int MAXN=1e5+100;
LL t,n,k;
LL a[MAXN];
LL solve(LL x)
{
    int last=0;
    LL num=0;
    int l,r;
    for(int i=1;i<=n;i++)
      if(a[i]>=x)
      {
          l=i;
          break;
      }
    r=l+1;
    while(r<=n)
    {
        if(a[r]>=x)
        {
          num+=(l-last)*(n-r+1);
          last=l;
          l=r;
          r=l+1;
        }
        else
        r++;
    }
    return num;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
      cin>>n>>k;
      for(int i=1;i<=n;i++)
      cin>>a[i];

      LL l=1,r=1e9+1;
      while(l+1<r)
      {
         LL mid=(l+r)/2;
         if(solve(mid)>=k)
         l=mid;
         else
         r=mid;
      }
      cout<<l<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/a249189046/p/8858564.html