您的位置:首页 > 产品设计 > UI/UE

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

2016-08-07 16:21 387 查看
题意:

求满足区间中>=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
,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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: