zoukankan      html  css  js  c++  java
  • [2020多校联考]双端队列xLIS问题

    Solution

    观察将一个序列按一定方法加入到双端队列的性质。发现若直接在队尾加入,则不会改变相对顺序,而加入到队头的元素实际上是原序列的某个子序列再反过来。干脆直接将原序列复制一份到前面再反转。那么答案就是这个新序列的最长上升子序列(考虑反转过去后,前后对应相等的两个元素不会同时出现在最长上升序列中)。

    用树状数组求最长上升子序列即可。

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define N 200007
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    int n,a[N],b[N],f[N],c[N];
    inline int max(int x,int y){return x>y? x:y;}
    inline int lowbit(int x){return -x&x;}
    inline void add(int x,int v){while(x<=n)c[x]=max(c[x],v),x+=lowbit(x);}
    inline int query(int x){int ret=0;while(x)ret=max(c[x],ret),x-=lowbit(x);return ret;}
    
    int main(){
        freopen("dequexlis.in","r",stdin);
        freopen("dequexlis.out","w",stdout);
        n=read();
        for(int i=1;i<=n;i++)
            a[i]=b[i]=a[i+n]=read();
        reverse(a+1,a+1+n);
        sort(b+1,b+1+n);
        int sz=unique(b+1,b+1+n)-(b+1),ans=0;
        for(int i=1;i<=n*2;i++){
            int x=lower_bound(b+1,b+1+n,a[i])-b;
            f[i]=query(x-1)+1;
            ans=max(ans,f[i]);
            add(x,f[i]);
        }
        printf("%d",ans);
    }
    
  • 相关阅读:
    Struts2 (二)入门
    Struts2 (一)入门
    Hibernate 配置和注解式 ,关联关系
    Hibernate入门,HQL,双向表关联关系
    web自定义标签
    Spring整合MyBatis 基础
    PHP字符串——字符串函数
    php功能模块学习笔记
    PHP常用符号和函数
    asp xmlhttp 读取文件
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/14036556.html
Copyright © 2011-2022 走看看