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);
    }
    
  • 相关阅读:
    位或( | )
    学习进度笔记7
    学习进度笔记6
    学习进度笔记5
    学习进度笔记4
    学习进度笔记3
    学习进度笔记2
    学习进度笔记1
    周总结13
    《黑客与画家》阅读笔记6
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13957239.html
Copyright © 2011-2022 走看看