FZU 2216 The Longest Straight 二分

0可以表示任何1到m的数,求一个最长的连续上升序列长度

因为m的范围在10w,所以以每个节点为起点 进行二分,复杂度mlogm

思路:b[i]表示到 1 到 i 有几个数没有出现,二分的时候注意加等号

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<queue>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int maxn=100000+5;
bool vis[maxn];
int b[maxn];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m,sum=0;
        scanf("%d%d",&n,&m);
        memset(vis,0,sizeof(vis));
        int x;
        for(int i=1; i<=n; ++i)
        {
            scanf("%d",&x);
            if(!x)sum++;
            else vis[x]=1;
        }
        b[0]=0;
        for(int i=1; i<=m; ++i)
        {
            if(vis[i])b[i]=b[i-1];
            else b[i]=b[i-1]+1;
        }
        int ans=1;
        for(int i=1; i<m; ++i)
        {
            int l=i,r=m,mid;
            while(l<=r)
            {
                mid=(l+r)>>1;
                if(b[mid]-b[i-1]>sum)r=mid-1;
                else l=mid+1;
            }
            mid=(l+r)>>1;
            ans=max(ans,mid-i+1);
        }
        printf("%d
",ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/shuguangzw/p/5083380.html