<span>HDU5806 NanoApe Loves Sequence Ⅱ(二分ortwo-pointer)</span>

题意:

求满足区间中>=m的数>=k个的区间有多少

思路:

记小于m的数为0,大于等于m的为1,用sum维护区间和

然后我的做法是枚举右端点,二分左端点得到答案,复杂度O(nlogn)

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int N=2e5+10;
int sum[N],k;
int fun(int p)
{
    int l=1,r=p;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(sum[p]-sum[mid]>=k) l=mid+1;
        else r=mid-1;
    }
    return r+1;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int t,n,m,x;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            sum[i]=sum[i-1]+(x>=m?1:0);
        }
        LL ans=0;
        int r;
        for(r=1;r<=n;r++) if(sum[r]>=k) break;
        for(int i=r;i<=n;i++) ans+=fun(i);
        printf("%I64d\n",ans);
    }
    return 0;
}

然后标解是two-pointer,处理完后枚举左端点,然后指针标记右端点

当区间内个数<k时就r++,大于n就跳出了,时间复杂度O(n)

这个题没有卡nlogn真是良心。。。

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int N=2e5+10;
int sum[N];
int main()
{
    //freopen("in.txt","r",stdin);
    int t,n,m,k,x;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            sum[i]=sum[i-1]+(x>=m?1:0);
        }
        LL ans=0;
        int r=1;
        for(int l=1;l<=n;l++)
        {
            while(r<=n&&sum[r]-sum[l-1]<k) r++;
            if(r>n) break;
            ans+=(n-r+1);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
全部评论

相关推荐

一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务