Luogu 4310 绝世好题
2024-08-24 01:14:45
BZOJ 4300
先把这堆东西丢到博客里,以后再复习。
首先考虑暴力的$dp$,设$f_i$表示以$i$结尾的满足条件的序列的最长长度,有:
$f_i = max(f_j) + 1$ $j < i $ $,$ $ a_j \& a_i \neq 0$
$ans = max(f_i)$ $1 \leq i \leq n$
这样是$n^2$的。
考虑二进制意义下的按位与,如果要使这个运算的结果不为$0$的话,必须要有一位两个数都是$1$,那么我们可以考虑拆位进行$dp$,设$g_j$表示第$j$位是$1$结尾的最长的满足条件的序列的长度。对于每一个$i$,有:
$f_i = max(g_j) + 1$ $0 \leq j \leq 32$ 并且$a_i$的第$j$位为$1$。
$g_j = max(f_i, g_j)$ $a_i$的第$j$位为$1$。
$ans = max(f_i)$ $1 \leq i \leq n$
事实上在写的时候并没有必要把$f$开出来。
时间复杂度$O(nlog(Maxn))$。
Code:
#include <cstdio>
#include <cstring>
using namespace std; const int N = 1e5 + ;
const int M = ; int n, a[N], f[M]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} int main() {
read(n);
for(int i = ; i <= n; i++) read(a[i]); int ans = ;
for(int i = ; i <= n; i++) {
int now = ;
for(int j = ; j <= ; j++)
if((a[i] >> j) & ) chkMax(now, f[j]);
++now;
chkMax(ans, now);
for(int j = ; j <= ; j++)
if((a[i] >> j) & ) chkMax(f[j], now);
} printf("%d\n", ans);
return ;
}
最新文章
- 解决Visual C++ Redistributable for Visual Studio 2015的安装问题
- Android深度探索--HAL与驱动开发----第九章读书笔记
- Fragment与FragmentAcitvity间的传值
- 嵌入式OS的现状、智能的物联网与未来的机器人
- 同域iframe的高度自适应
- [转]怎样解决Myeclipse内存溢出?
- Gradle用户指南(章8:依赖关系管理基础)
- Android中“再按一次返回键退出程序”实现
- URAL(DP集)
- 【转】SVN linux命令及 windows相关操作(二)
- C#中的Virtual
- Linux查看命令终止进程
- OpenGL ES 详解纹理生成和纹理映射步骤以及函数
- java数组中取出最大值
- 【二分+容斥+莫比乌斯反演】BZOJ2440 完全平方数
- Contest2163 - 2019-3-28 高一noip基础知识点 测试6 题解版
- jdk5升8问题记录-Spring2升4
- 【angularjs】使用angularjs模拟淘宝首页-淘宝头条滚动效果
- 当我new class的时候,提示以下错误: Unable to parse template ";Class"; Error message: This template did not produce a Java class or an interface Error parsing file template: Unable to find resource &#39;Package Header.j
- 设计模式---状态变化模式之state状态模式(State)