hiho about the 1483 range Value 241 weeks

Disclaimer: the author is limited, blog inevitably a lot of flaws and even serious mistakes, I hope you correct. While writing the biggest goal is also to exchange learning, not paying attention and spread. Long way to go, and you encourage each other. https://blog.csdn.net/yexiaohhjk/article/details/87432735

Questions surface:

Link

Meaning of the questions:

The number n, the number of times that they are the same value range of numbers, for the value of k-th largest value n is the number of intervals?

Ideas:

Most violent determined n * (n + 1) / 2 different interval value, then ordering k-th largest value seeking obviously TLE.
Our first analysis found that the greater the range, certainly the greater the value, and was monotonic. We can use to find a large binary value of k.
Check for each of the two points, taken here thought on foot, foot taken from left to right over the maximum sweep interval [L, R] values are in less than two minutes mid, after accumulation can O(n)count the number n of the time in value than the small number of mid range, the total time complexity becomes O(nlogn). Map may be used when the time-out count the number of occurrences of each, and n ranges may be able to save an array, but the value is too large, then a discrete operation.

Code

#include<bits/stdc++.h>
using namespace std;
const int N = 200010;
typedef long long ll;
ll a[N],temp[N],n,k;
int vis[N];
ll check(ll mid)//尺取求比mid小的区间个数
{
    ll sum = 0,num = 0;
    memset(vis,0,sizeof(vis));
    for(int i=0,j=0;i<n;i++)
    {
        for(;j<n&&sum+vis[a[j]]<=mid;j++)
        {
            sum += vis[a[j]];
            vis[a[j]]++;
        }
        num += j-i;//当前i,j范围内i作为起点的j个不同区间内值都比mid小
        vis[a[i]]--;
        sum -= vis[a[i]];
    }
    return num>=k;
}


int main(){
    int T;cin>>T;
    while(T--){
        cin>>n>>k;
        for(int i=0;i<n;i++){
            cin>>a[i];
            temp[i] = a[i];
        }
        int cnt;
        sort(temp,temp+n);
        cnt = unique(temp,temp+n) - temp;
        for(int i=0;i<n;i++){
            a[i] = lower_bound(temp,temp+cnt,a[i]) - temp; //离散化操作
        }
        ll l= 0,r = n*(n-1)/2;
        while(l<=r){
            ll mid = (l+r)/2;
            if(check(mid)) r = mid-1;//说明mid大了
            else l = mid+1;
        }
        cout<<r+1<<endl;
    }
}

Guess you like

Origin blog.csdn.net/yexiaohhjk/article/details/87432735
241