HDU 6231(二分&双指针)

HDU 6231(二分&双指针)HDU 6231 二分 amp 双指针 分为几个步骤 1 二分枚举答案 2 对于每个枚举的答案 x x x 找到有多少个区间的第 k k k 大 x

大家好,我是讯享网,很高兴认识大家。

HDU 6231(二分&双指针)

分为几个步骤:

1.二分枚举答案

2.对于每个枚举的答案 x x x找到有多少个区间的第 k k k ≥ x \ge x x

瓶颈之处在于步骤2.

我们需要在 O ( n ) O(n) O(n)内求出来。

若一个区间的第 k k k ≥ x \ge x x,则说明至少有 k k k个数 ≥ x \ge x x


讯享网

考虑双指针。

枚举 l l l,然后找到刚好出现 k k k个数 ≥ x \ge x x的位置 r r r,然后此位置 l l l的答案是: n − r + 1 n-r+1 nr+1

显然当 l l l递增时, r r r是非递减的。

所以双指针是正确的。

总的时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

// Problem: B - K-th Number // Contest: Virtual Judge - 2017CCPC 哈尔滨 [Cloned] // URL: https://vjudge.net/contest/#problem/B // Memory Limit: 262 MB // Time Limit: 1000 ms // Date: 2021-05-04 23:47:41 // --------by Herio-------- #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7; #define mst(a,b) memset(a,b,sizeof a) #define PII pair<int,int> #define fi first #define se second #define pb emplace_back #define SZ(a) (int)a.size() #define IOS ios::sync_with_stdio(false),cin.tie(0)  void Print(int *a,int n){ 
    for(int i=1;i<n;i++) printf("%d ",a[i]); printf("%d\n",a[n]); } int a[N]; int n,k; ll m; bool ck(int x){ 
    int c=0,r=1; ll s=0; for(int l=1;l<=n;l++){ 
    while(r<=n&&c<k){ 
    if(a[r]>=x) c++; r++; } if(c==k) s+=n-r+2; if(a[l]>=x) c--; } return s>=m; } int main(){ 
    int t;scanf("%d",&t); while(t--){ 
    scanf("%d%d%lld",&n,&k,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int l=0,r=1e9,ans; while(l<=r){ 
    int mid=l+r>>1; if(ck(mid)) l=mid+1,ans=mid; else r=mid-1; } printf("%d\n",ans); } return 0; } 

讯享网
小讯
上一篇 2025-01-19 14:27
下一篇 2025-03-26 17:50

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/34352.html