BZOJ 4300: 绝世好题

Description

给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len)。
 

Input

输入文件共2行。
第一行包括一个整数n。
第二行包括n个整数,第i个整数表示ai。
 

Output

输出文件共一行。
包括一个整数,表示子序列bi的最长长度。
 

Sample Input

3
1 2 3

Sample Output

2

HINT

n<=100000,ai<=2*10^9

 

/*
    f[j]表示a[i]的二进制位的第j位是1的最大子序列长度。
    那么 找出a[i]的所有二进制位上为1的f[]中的最大值maxn,然后让所有二进制位上为1的f[]=maxn+1 (因为加上了a[i]) 
*/ 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int N=1e5+5;

int n;
int a[N],f[35];

int read()
{
    char c=getchar();int num=0,f=-1;
    for(;!isdigit(c);c=getchar())
        if(c=='-')
            f=-1;
    for(;isdigit(c);c=getchar())
        num=num*10+c-'0';
    return num*f;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    for(int i=1,maxn=0;i<=n;maxn=0,++i)
    {
        for(int j=0;j<=30;++j)
            if(a[i]&(1<<j))
                maxn=max(maxn,f[j]);
        ++maxn;
        for(int j=0;j<=30;++j)
            if(a[i]&(1<<j))
                f[j]=max(f[j],maxn);
    }
    printf("%d",*max_element(f,f+31));
    return 0;
}

 

posted @ 2018-02-12 14:19  whymhe  阅读(86)  评论(0编辑  收藏  举报