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;
    }
  • 相关阅读:
    Javascript创建对象的几种方式
    web化的远程桌面
    (原创) Asp.net XPS HighLight(高亮)CreateWatermark(水印 )
    C# 序列化和反序列化
    删除 HttpCookie
    (轉)AlertBox 彈出層(真的不錯哦)
    净高误差超过20mm
    如何处理并发
    ORM性能比对
    STL源码iterator和traits编程技法
  • 原文地址:https://www.cnblogs.com/albert7xie/p/4963400.html
Copyright © 2011-2022 走看看