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;
    }
  • 相关阅读:
    以正确的方式开源 Python 项目
    一个备胎的自我修养
    关于我们 | 读书马上
    基于libevent, libuv和android Looper不断演进socket编程
    libuv 与 libev 的对比
    OCaml Language Sucks
    Practical Common Lisp
    learning
    WebApi系列~QQ互联的引入(QConnectSDK)
    知方可补不足~用xsl来修饰xml
  • 原文地址:https://www.cnblogs.com/albert7xie/p/4963400.html
Copyright © 2011-2022 走看看