1. 程式人生 > >【BZOJ4300】絕世好題

【BZOJ4300】絕世好題

                                         4300: 絕世好題

                                                 Time Limit: 1 Sec  Memory Limit: 128 MB                                                           Submit: 2979  Solved: 1613

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

解析:

       最初只會O(N^2)。。。

       但是我們觀察到,每往B中加進一個數,這個數只跟加進來前隊尾的數有關,所以就可以列舉二進位制上的每一位進行DP轉移了,令f[i]為加入當前數後第i位為1的最大值。

程式碼:  

#include <bits/stdc++.h>
using namespace std;

int n,ans;
int f[40];

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') f=-1,c=getchar();
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}

int main()
{
	scanf("%I64d",&n);
	for(int i=1;i<=n;++i)
	{
		int x=get_int(),tmp=0;
		for(int j=0;(1<<j)<=x;++j)if((1<<j)&x)tmp=max(tmp,f[j]);
		++tmp;
		for(int j=0;(1<<j)<=x;++j)if((1<<j)&x)f[j]=tmp;
	}
	for(int i=0;i<=39;i++) ans=max(ans,f[i]);
	cout<<ans;
	return 0;
}