• HDU5806 NanoApe Loves Sequence Ⅱ(二分ortwo-pointer)


    题意:

    求满足区间中>=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
    ",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
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    贪心算法
    分治法
    递归法
    查找二 树与图的搜索
    (转载)查找三 哈希表的查找
    (转载)查找一 线性表的查找
    4.写出完整版的strcpy函数
    3.strcpy使用注意(3)
    2.strcpy使用注意(2)
    1.strcpy使用注意
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5746471.html
Copyright © 2020-2023  润新知