• [HEOI/TJOI2016]序列


    Description:

    给你一个序列,每个数可能变化为另一个数,每次最多有一个数变化

    求最长的子序列,无论如何变化,这个子序列都不下降

    Hint:

    (n le 10^5)

    Solution:

    没想到是dp

    设f[i]表示以i结尾的最长长度,有:

    [f[i]=f[j]+1 ]

    [当max_j<val_i,val_j<min_i ]

    然后cdq直接搞一波,注意排序那里要魔改一下

    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ls p<<1 
    #define rs p<<1|1
    using namespace std;
    typedef long long ll;
    const int mxn=2e5+5,inf=1e9;
    int n,m,cnt,f[mxn],tr[mxn],hd[mxn];
    
    inline int read() {
        char c=getchar(); int x=0,f=1;
        while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
        while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
        return x*f;
    }
    inline void chkmax(int &x,int y) {if(x<y) x=y;}
    inline void chkmin(int &x,int y) {if(x>y) x=y;}
    
    struct ed {
        int to,nxt;
    }t[mxn<<1];
    
    inline void add(int u,int v) {
        t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
    }
    
    struct Q {
        int val,mx,mi,id;
    }T[mxn];
    
    int cmpv(Q x,Q y) {
        return x.val<y.val;
    }
    
    int cmpm(Q x,Q y) {
        return x.mx<y.mx;
    }
    
    int cmpi(Q x,Q y) {
        return x.id<y.id;
    }
    
    void mod(int x,int y,int opt) {
        while(x<=n) {
            if(opt) chkmax(tr[x],y);
            else tr[x]=-inf;
            x+=(x&-x);
        }
    }
    
    int query(int x) {
        int res=-inf;
        while(x) {
            chkmax(res,tr[x]);
            x-=(x&-x);
        }
        return res;
    }
    
    void cdq(int l,int r) {
        if(l==r) return ;
        int mid=(l+r)>>1;
        cdq(l,mid);
        sort(T+l,T+mid+1,cmpm);
        sort(T+mid+1,T+r+1,cmpv);
        int pos=l; //这里写错了几次
        for(int i=mid+1;i<=r;++i) { 
            while(T[pos].mx<=T[i].val&&pos<=mid) 
                mod(T[pos].val,f[T[pos].id],1),++pos;
            chkmax(f[T[i].id],query(T[i].mi)+1);	
        }
        for(int i=l;i<pos;++i) mod(T[i].val,0,0);
        sort(T+l,T+r+1,cmpi); //dp型cdq千万别忘记重排
        cdq(mid+1,r);	
    }
    
    int main()
    {
        n=read(); m=read(); int x,y; memset(tr,0x80,sizeof(tr));
        for(int i=1;i<=n;++i) T[i].val=T[i].mx=T[i].mi=read(),T[i].id=i;
        for(int i=1;i<=m;++i) {
            x=read(); y=read();
            chkmin(T[x].mi,y);
            chkmax(T[x].mx,y);
        }
        for(int i=1;i<=n;++i) f[i]=1; 
        cdq(1,n); int ans=0;
        for(int i=1;i<=n;++i) chkmax(ans,f[i]);
        printf("%d",ans);
        return 0;
    }
    
    
  • 相关阅读:
    vue报错:Not Found
    使用Vue DevTools 插件报错的问题:Vue.js is detected on this page. Open DevTools and look for the Vue panel.
    Linux安装docker
    asp.net5.0源码(Microsoft github源码)
    探索Asp net core3中的 项目文件、Program.cs和通用host(转)
    c#中的sealed关键字
    .NET平台常见技术框架整理汇总
    疫情下孩子的网课
    常系数齐次线性递推
    【2021~2022】模拟赛乱写 Period I
  • 原文地址:https://www.cnblogs.com/list1/p/10637651.html
Copyright © 2020-2023  润新知