Codeforces 1175F The Number of Subpermutations (思维+rmq)

Meaning of the questions:

Seeking interval [l, r] is the number of sections arranged in a 1 ~ r-l + 1 of

n<=3e5

Ideas:

If [l, r] is a permutation, the first number there should vary, and should max (l, r) is equal to r-l + 1, which can uniquely determine the range of the condition

We only require pretreatment left out, for each point, it extends to the furthest r, such that r l to vary, and violence

Note that if is not satisfied for a violent max (l, r) == r-l + 1, then the time should skip r l + max (r-l + 1) -1, because here it may satisfy the condition of at least

Code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
    
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) 

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 2e6+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);
int a[maxn];
int d[maxn][25];
int n;
void init(){
    for(int i = 1; i <= n; i++) d[i][0] =a[i];
    for(int j = 1; (1<<j) <= n; j++){
        for(int i = 1; i + (1<<j) - 1 <= n; i++){
            d[i][j] = max(d[i][j-1], d[i + (1<<(j-1))][j-1]);
        }
    }
}
int rmq(int l, int r){
    int k = 0;
    while((1<<(k+1)) <= r-l+1)k++;
    return max(d[l][k], d[r-(1<<k)+1][k]);
}
int mx[maxn];
int id[maxn];
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    mx[n+1]=n;
    for(int i = n; i >= 1; i--){
        if(id[a[i]])mx[i]=min(mx[i+1],id[a[i]]-1);
        else mx[i]=mx[i+1];
        id[a[i]]=i;
    }
    init();
    int ans=0;
    for(int i = 1; i <= n; i++){
        int j = i;
        while(j<=mx[i]){
            //printf("%d %d %d\n",i,j,rmq(i,j));
            if(rmq(i,j)==j-i+1){ans++;j++;}
            else j=i+rmq(i,j)-1;
        }
    }
    printf("%d",ans);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/wrjlinkkkkkk/p/10988157.html