【BZOJ 4300】绝世好题
2015-11-13 22:21
441 查看
4300: 绝世好题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 540 Solved: 278
[Submit][Status][Discuss]
Description
给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len)。Input
输入文件共2行。第一行包括一个整数n。
第二行包括n个整数,第i个整数表示ai。
Output
输出文件共一行。包括一个整数,表示子序列bi的最长长度。
Sample Input
31 2 3
Sample Output
2HINT
对于100%的数据,1<=n<=100000,ai<=10^9。Source
By Oxer题目如此之霸气,然而内在却水得一败涂地。
然而不难想到O(N2)的算法,就是一个简单LIS,条件不同罢了。
加一点优化,我们不难知道我们只要从前面选一个最大加1就行了(LIS就是这么做的哦),所以我们需要一个快速查找的东西。
我们把数都看成二进制(最长也只有31位),那么我们只需要知道当前这个数的某一二进制位和前面的都是1,那么&运算后的结果肯定不为0了。
很简单吧。就这样就变成O(Nlog2ai)的算法。虽然表达有点诡异,但是大家懂了就行。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int maxbit[35], a, n; void update(int x, int delx) { for (int i = 0; x != 0; (x >>= 1), ++i) if (x & 1) maxbit[i] = max(maxbit[i], delx); } int query(int x) { int maxt = 0; for (int i = 0; x != 0; (x >>= 1), ++i) if (x & 1) maxt = max(maxt, maxbit[i]); return maxt; } int main() { scanf("%d", &n); scanf("%d", &a); int ans = 1; memset(maxbit, 0, sizeof(maxbit)); update(a, 1); for (int i = 1; i < n; ++i) { scanf("%d", &a); int maxnow = query(a) + 1; update(a, maxnow); ans = max(ans, maxnow); } printf("%d\n", ans); return 0; }
相关文章推荐
- Java基础增强(二):注解
- (转)窗函数(window function)
- (解题报告)NOJ1094--蛇形填数1
- XMLDLL操作说明文档(二)
- matlab从图片中简单识别红色物体
- JAVA 多态和异常处理作业——动手动脑以及课后实验性问题
- zoj 3870
- dancing links解决X问题的C++实现
- 团队作业--冲刺总结
- 关于SQL Server中分区表的文件与文件组的删除(转)
- 区域赛系列一多边形划分(卡特兰数)
- js与java的冒泡排序
- 杭电1247
- 菜鸟如何成为一个高效程序员的成长之路
- 常见的JS排序算法
- 黑马程序员——Java集合框架复习总结(三)
- [BZOJ4034] [HAOI2015]T2
- 日经春秋 20151113
- 大道至简第7,8章读后感
- 明天可以自动签到啦!!!