zoukankan      html  css  js  c++  java
  • 题解-CF1437E Make It Increasing

    题面

    CF1437E Make It Increasing

    (n) 个数 (a_i),固定 (k) 个下标 (b_i),求只修改不在 (b_i) 中的下标的值使 (a_i) 严格单调递增的最少修改次数。

    数据范围:(1le nle 5cdot 10^5)(0le kle n)


    题解

    分成 (k+1) 段做没有问题,蒟蒻的做法是线段树维护 dp

    旁边老爷的做法是区间长度减去最长上升子序列长度,蒟蒻没想到,还想了单调队列优化好久。

    题目转化为对于一个区间,第一个元素最后一个元素固定的最少修改次数。

    (a_i) 减去 (i),就变成非严格单调递增了。

    (f_i) 表示不修改 (i) 的前缀最少修改次数。

    [f_i=min_{j=1,a_jle a_i}^{i-1} (f_j+i-j-1)Longrightarrow f_i=i-1+min_{j=1,a_jle a_i}^{i-1}( f_j-j) ]

    所以可以建一个 (a_i) 值域线段树,值为 (f_i-i)

    (f_i) 的值就是当前线段树 ([0,a_i]) 之间的最大值 (+i-1)

    每次求出 (f_i) 后在 (a_i) 上更新 (f_i-i) 即可。


    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef double db;
    #define mp(a,b) make_pair((a),(b))
    #define x first
    #define y second
    #define bg begin()
    #define ed end()
    #define sz(a) int((a).size())
    #define pb(a) push_back(a)
    #define R(i,a,b) for(int i=(a),i##E=(b);i<i##E;i++)
    #define L(i,a,b) for(int i=(b)-1,i##E=(a)-1;i>i##E;i--)
    const int iinf=0x3f3f3f3f;
    const ll linf=0x3f3f3f3f3f3f3f3f;
    
    //Data
    const int N=5e5+2;
    int n,a[N],dn,d[N],k,b[N],ans;
    
    //SegmentTree
    const int tN=N<<2;
    #define mid ((l+r)>>1)
    int mn[tN];
    void build(int k=0,int l=0,int r=dn){
        mn[k]=iinf; if(r-l==1) return;
        build(k*2+1,l,mid),build(k*2+2,mid,r);
    }
    void pushup(int k){mn[k]=min(mn[k*2+1],mn[k*2+2]);}
    void fixmn(int x,int v,int k=0,int l=0,int r=dn){
        if(r<=x||x+1<=l) return;
        if(r-l==1) return mn[k]=min(mn[k],v),void();
        fixmn(x,v,k*2+1,l,mid),fixmn(x,v,k*2+2,mid,r),pushup(k);
    }
    int rangemn(int x,int y,int k=0,int l=0,int r=dn){
        if(r<=x||y<=l) return iinf; if(x<=l&&r<=y) return mn[k];
        return min(rangemn(x,y,k*2+1,l,mid),rangemn(x,y,k*2+2,mid,r));
    }
    
    //DP
    int tmp[N];
    int dp(int* arr,int len){
        R(i,dn=0,len) d[dn++]=arr[i];
        sort(d,d+dn),dn=unique(d,d+dn)-d;
        R(i,0,len) tmp[i]=lower_bound(d,d+dn,arr[i])-d;
        build(),fixmn(tmp[0],0); int res=-1;
        R(i,1,len){
            res=rangemn(0,tmp[i]+1)+i-1;
            fixmn(tmp[i],res-i);
        }
        // R(i,0,len) cout<<arr[i]<<' ';cout<<'
    ';
        // R(i,0,len) cout<<f[i]<<' ';cout<<'
    ';
        // cout<<f[len-1]<<'
    ';
        return res;
    }
    
    //Main
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0),cout.tie(0);
        cin>>n>>k,a[0]=-iinf,a[n+1]=+iinf;
        R(i,1,n+1) cin>>a[i],a[i]-=i;
        R(i,0,k) cin>>b[i];
        R(i,1,k)if(a[b[i]]<a[b[i-1]]) cout<<-1<<'
    ',exit(0);
        if(k==0) ans=dp(a,n+2);
        else {
            ans+=dp(a,b[0]+1);
            R(i,1,k) ans+=dp(a+b[i-1],b[i]-b[i-1]+1); 
            ans+=dp(a+b[k-1],n-b[k-1]+2);
        }
        cout<<ans<<'
    ';
        return 0;
    }
    

    祝大家学习愉快!

  • 相关阅读:
    北京联通光猫WO-36(HG220GS-U)改为桥接模式
    使用DataGrip导入数据
    Spring知识点
    mybatis-generator
    项目中mybatis连接mysql常见问题
    Spring AOP
    Volatile
    Redis知识点
    Spring IOC
    Observer模式
  • 原文地址:https://www.cnblogs.com/George1123/p/13891553.html
Copyright © 2011-2022 走看看