zoukankan      html  css  js  c++  java
  • 【BZOJ 4300】绝世好题

    4300: 绝世好题

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 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

    3
    1 2 3

    Sample Output

    2

    HINT

    对于100%的数据,1<=n<=100000,ai<=10^9。


    Source

     
    题目如此之霸气,然而内在却水得一败涂地。
    然而不难想到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
    ", ans);
        return 0;
    }
  • 相关阅读:
    PLSQL查询显示乱码或者问号
    Sonar 扫描C#代码 排除文件
    C# 短日期转换为DateTime
    电脑远程连接不上或者ip的地址一直是169.254
    C#导出CSV或者EXCEL文件转换文本
    Oracle 计算两个日期相差天时分秒
    Linux 做网关
    Python 内置函数
    Python Fileinput 模块
    Python-2.7 配置 tab 自动补全功能
  • 原文地址:https://www.cnblogs.com/albert7xie/p/4963400.html
Copyright © 2011-2022 走看看