zoukankan      html  css  js  c++  java
  • HDU 3564 Another LIS

    题意:
    有一个起初是空的序列。我们开始在序列中添加从1到N的数字,每次我们只在特定位置向序列添加一个数字。现在,我们想知道每次添加后LIS(最长上升子序列)的长度。
    题解:
    一个神奇的LIS题,题解见附件

    #pragma GCC optimize (4)
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=100000+10;
    #define min(x,y) ((x)<(y)?(x):(y))
    #define max(x,y) ((x)>(y)?(x):(y))
    namespace GET{
        char ch;
        inline char read(){
            #define MAX 10000000
            static char buf[MAX],*s,*t;
            if(s==t){
                t=(s=buf)+fread(buf,1,MAX,stdin);
                if(s==t)return EOF;
            }
            return *s++;
        }
        // #define getchar read
        template <typename T>
        inline void Read(T &x){
            while(ch<'0'||ch>'9')ch=getchar();
            x=ch-'0';ch=getchar();
            while(ch>='0'&&ch<='9'){
                x=(x<<1)+(x<<3)+(ch^'0');
                ch=getchar();
            }
        }
        inline void Write(int x){
            if(x>10)Write(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace GET;
    struct Tree{
            int left,right;
            int sum;
    }a[maxn<<2];
    int n,ans;
    int A[maxn],Low[maxn],val[maxn];
    void Init();
    void LIS();
    void Pushup(int);
    void Build(int,int,int);
    void Update(int,int,int);
    signed main(){
            // freopen("in.cpp","r",stdin);
            Init();
            return 0;
    }
    void Init(){
            Read(n);
            Build(1,1,n);
            for(int i=1;i<=n;i++)Read(A[i]);
            for(int i=n;i>=1;i--)Update(1,i,A[i]+1);
            LIS();
    }
    void LIS(){
            Low[1]=val[1];ans=1;//val记录最终的序列
            printf("%d
    ",ans );
            for(int i=2;i<=n;i++){//接下来的就是二分求LIS
                    int x=lower_bound(Low+1,Low+1+ans,val[i])-Low;
                    ans=max(x,ans);
                    Low[x]=val[i];
                    printf("%d
    ",ans);
            }
    }
    void Pushup(int u){
            a[u].sum=a[u<<1].sum+a[u<<1|1].sum;
    }
    void Build(int u,int left,int right){
            a[u].left=left;a[u].right=right;
            if(left==right){
                    a[u].sum=1;return;
            }
            int mid=(left+right)>>1;
            Build(u<<1,left,mid);
            Build(u<<1|1,mid+1,right);
            Pushup(u);
    }
    void Update(int u,int key,int p){
            if(a[u].left==a[u].right){
                    val[key]=a[u].left;
                    a[u].sum=0;
                    return;
            }
            a[u].sum--;
            int mid=(a[u].left+a[u].right)>>1;
            if(a[u<<1].sum>=p)Update(u<<1,key,p);
            else Update(u<<1|1,key,p-a[u<<1].sum);
    }

     

  • 相关阅读:
    子类调用父类被重写的方法
    Linux下编译出现undefined reference to ‘pthread_create’问题解决
    CRC校验8
    嵌入式C语言查表法
    Static关键字,遇到的问题_1
    java中方法的参数传递机制_一个对象被当作参数传递到一个方法后
    String使用equals和==比较的区别
    如何导入XML数据 (python3.6.6区别于python2 环境)
    0xx_PHP核心01
    PHP_MVC设计模式02
  • 原文地址:https://www.cnblogs.com/holy-unicorn/p/9510360.html
Copyright © 2011-2022 走看看