zoukankan      html  css  js  c++  java
  • 辉夜大小姐想让我构造不降序列 双指针+思维

    辉夜大小姐想让我构造不降序列 双指针+思维

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6+10;
    /*
    题解:
    首先得到 f(1,r) 的一个区间,然后容易得到 f(2,x) 这个x>r(这个可以自己思考一下)
    所以就有点像双指针。
    对于每一个区间 f(l,r),我都应该判断 l-1 之前的都是顺序的,r+1之后都是顺序的
    并且最小的 (r+1,n) 的位置要大于最大的 (1,l-1) 这个位置
    */
    int lc[maxn],rc[maxn],L[maxn],R[maxn],pre[maxn],last[maxn];
    bool check(int x,int y){
        if(pre[x-1]&&last[y+1]&&L[y+1]>R[x-1]) return true;
        return false;
    }
    int main(){
        int n,x;
        scanf("%d%d",&n,&x);
        memset(L,inf,sizeof(L));
        memset(lc,inf,sizeof(lc));
        for(int i=1,v;i<=n;i++) {
            scanf("%d",&v);
            lc[v] = min(lc[v],i);
            rc[v] = max(rc[v],i);
        }
        for(int i=x;i>=1;i--){
            L[i] = min(L[i+1],lc[i]);
        }
        for(int i=1;i<=x;i++){
            R[i] = max(R[i-1],rc[i]);
        }
        pre[0] = 1;
        for(int i=1;i<=x;i++){
            pre[i] = pre[i-1]&(R[i-1]<lc[i]);
        }
        last[x+1] = 1;
        for(int i=x;i>=1;i--){
            last[i] = last[i+1]&(L[i+1]>rc[i]);
        }
        ll ans = 0;
        int now = 1;
        for(int i=1;i<=x;i++){
            while(now<i) now++;
            while(now<=x&&!check(i,now)) now++;
            if(check(i,now)) ans+= x - now + 1;
        }
        printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    微信消息类型和事件类型
    lnmp环境搭建脚本
    laravel框架踩过的坑
    vue结构详解
    PHP消息队列实现及应用
    laravel 运行错误
    笔记分享
    cf730e
    cf 730i
    cf 731f
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13957239.html
Copyright © 2011-2022 走看看