zoukankan      html  css  js  c++  java
  • [HEOI2016] 序列

    Description

    有n个数,每个数有若干取值,但是只能在原数列的一个位置变换取值,求一个最长上升子序列,满足无论数列如何变化,这都是一个最长上升子序列。

    Solution

    记录 (l[i],r[i]) 分别表示 (i) 能取到的最大最小值,(val[i]) 为原数列。

    我们来看看满足条件的二元组 (i,j) 满足什么条件。

    1. (i<j)
    2. (val[i]<val[j])
    3. (r[i]<val[j])
    4. (val[i]<l[j])

    观察到条件2包含在条件3,4里。

    二维偏序问题,上CDQ就行。

    Code

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    #define N 100005
    #define min(A,B) ((A)<(B)?(A):(B))
    #define max(A,B) ((A)>(B)?(A):(B))
    #define swap(A,B) ((A)^=(B)^=(A)^=(B))
    
    int f[N];
    int ans[N];
    int n,m,len;
    int last[N];
    
    struct Node{
        int val,l,r,idx;
    }node[N];
    
    bool cmp(Node x,Node y){
        return x.l<y.l;
    }
    
    bool cmp2(Node x,Node y){
        return x.idx<y.idx;
    }
    
    bool cmp3(Node x,Node y){
        return x.val<y.val;
    }
    
    void add(int x,int y){
        for(;x<=len;x+=x&-x)
            f[x]=max(f[x],y);
    }
    
    int query(int x){
        int now=0;
        for(;x;x-=x&-x)
            now=max(now,f[x]);
        return now;
    }
    
    int getint(){
        int x=0,f=0;char ch=getchar();
        while(!isdigit(ch)) f|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        return f?-x:x;
    }
    
    void cdq(int l,int r){
        if(l>=r) return;
        int mid=l+r>>1;
        cdq(l,mid);
        std::sort(node+l,node+mid+1,cmp3);
        std::sort(node+mid+1,node+r+1,cmp);
        int a=l; memset(f,0,sizeof f);
        for(int j=mid+1;j<=r;j++){
            while(a<=mid and node[a].val<=node[j].l){
                add(node[a].r,ans[node[a].idx]);
                a++;
            }
            int p=query(node[j].val);
            ans[node[j].idx]=max(ans[node[j].idx],p+1);
        }
        std::sort(node+l,node+r+1,cmp2);
        cdq(mid+1,r);
    }
    
    signed main(){
        n=getint(),m=getint();
        for(int i=1;i<=n;i++){
            ans[i]=1;
            node[i].val=node[i].l=node[i].r=getint();
            len=max(len,node[i].l);
            node[i].idx=i;
        }
        for(int i=1;i<=m;i++){
            int x=getint(),y=getint();
            len=max(len,y);
            node[x].r=max(node[x].r,y);
            node[x].l=min(node[x].l,y);
        }
        cdq(1,n);
        int maxn=0;
        for(int i=1;i<=n;i++)
            maxn=max(maxn,ans[i]);
        printf("%d
    ",maxn);
        return 0;
    }
    
  • 相关阅读:
    Representation Data in OpenCascade BRep
    Render OpenCascade Geometry Surfaces in OpenSceneGraph
    Render OpenCascade Geometry Curves in OpenSceneGraph
    OpenCascade Shape Representation in OpenSceneGraph
    Geometry Surface of OpenCascade BRep
    Geometry Curve of OpenCascade BRep
    Tyvj2017清北冬令营入学测试
    Spfa算法模板
    洛谷1016 旅行家的预算
    洛谷1290 欧几里得的游戏
  • 原文地址:https://www.cnblogs.com/YoungNeal/p/9374452.html
Copyright © 2011-2022 走看看