C. Almost Increasing Subsequence

258 阅读2分钟

A sequence is almost-increasing if it does not contain three consecutive elements x,y,zx,y,z such that x≥y≥zx≥y≥z.

You are given an array a1,a2,…,ana1,a2,…,an and qq queries.

Each query consists of two integers 1≤l≤r≤n1≤l≤r≤n. For each query, find the length of the longest almost-increasing subsequence of the subarray al,al+1,…,aral,al+1,…,ar.

A subsequence is a sequence that can be derived from the given sequence by deleting zero or more elements without changing the order of the remaining elements.

Input The first line of input contains two integers, nn and qq (1≤n,q≤2000001≤n,q≤200000) — the length of the array aa and the number of queries.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109) — the values of the array aa.

Each of the next qq lines contains the description of a query. Each line contains two integers ll and rr (1≤l≤r≤n1≤l≤r≤n) — the query is about the subarray al,al+1,…,aral,al+1,…,ar.

Output For each of the qq queries, print a line containing the length of the longest almost-increasing subsequence of the subarray al,al+1,…,aral,al+1,…,ar. 如果一个序列不包含三个连续的元素x,y,zx,y,z,使x≥y≥zx≥y≥z,那么它就是几乎递增的。

给你一个数组a1,a2,...,ana1,a2,...,an和qq查询。

每个查询由两个整数1≤l≤r≤n1≤l≤r≤n组成。对于每个查询,找出子阵列al,al+1,...,ral,al+1,...,ar的最长的几乎递增的子序列的长度。

子序列是指在不改变剩余元素顺序的情况下,通过删除零个或多个元素,可以从给定的序列中得到的序列。

Example

#include<bits/stdc++.h>
#define int long long

using namespace std;

typedef pair<int, int> PII;
const int N = 200010, MOD = 1000000007;
int n, m;
int a[N], s[N];

void solve()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    vector<PII> seg;
    for(int i = 1; i <= n; i++)
    {
        int j = i;
        while(j + 1 <= n && a[j + 1] <= a[j])
            j ++;
        seg.push_back({i, j});
        i = j;
    }
    for(auto v : seg)
    {
    	int x=v.first,y=v.second;
        s[x] = s[x - 1] + 1;
        for(int i = x + 1; i <= y; i++)
        {
            if(i == x + 1)
                s[i] = s[i - 1] + 1;
            else
                s[i] = s[i - 1];
        }
    }
    while(m --)
    {
        int l, r;
        cin >> l >> r;
        if(r - l + 1 <= 2)
        {
            cout << r - l + 1 << "\n";
            continue;
        }
        int ans = s[r] - s[l - 1];
        if(a[l - 2] >= a[l - 1] && a[l - 1] >= a[l])
            ans ++;
        if(a[l - 1] >= a[l] && a[l] >= a[l + 1])
            ans ++;
        cout << ans << "\n";
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T = 1;
    //cin >> T;
    while(T--) {
        solve();
    }
}