• [CF1437E] Make It Increasing(LIS)


    原题

    You are given an array of nn integers (a1, a2, ..., an), and a set bb of kk distinct integers from (1) to (n).

    In one operation, you may choose two integers (i) and (x (1≤i≤n1≤i, x) can be any integer) and assign (ai:=x). This operation can be done only if ii does not belong to the set bb.

    Calculate the minimum number of operations you should perform so the array aa is increasing (that is, (a_1<a_2<a_3<⋯<a_n)), or report that it is impossible.

    Input

    The first line contains two integers nn and (k (1≤n≤5⋅10^5, 0≤k≤n)) — the size of the array aa and the set bb, respectively.

    The second line contains nn integers (a_1, a_2, ..., a_n (1≤a_i≤10^9)).

    Then, if (k≠0), the third line follows, containing (k) integers (b_1, b_2, ..., b_k (1≤b_1<b_2<⋯<b_k≤n)). If k=0, this line is skipped.

    Output

    If it is impossible to make the array aa increasing using the given operations, print (−1).

    Otherwise, print one integer — the minimum number of operations you have to perform.

    Examples

    input

    7 2
    1 2 1 1 3 5 1
    3 5
    

    output

    4
    

    input

    3 3
    1 3 2
    1 2 3
    

    output

    -1
    

    input

    5 0
    4 3 1 2 3
    

    output

    2
    

    input

    10 3
    1 3 5 6 12 9 8 10 13 15
    2 4 9
    

    output

    3
    

    题意

    对于一个序列,k个给定位置的数不能动,其它位置的数可以改成任意数,使其变成严格递增序列(前一个数不能等于后一个数)的最小改变次数。

    思路

    把序列根据给定的k位置,把序列分成k + 1个区间,对每个区间求最长严格递增子序列,并且每个选择的数不能小于左端点,不能大于右端点。区间长度减去当前区间最长严格递增子序列长度之和即最后的答案。

    因为最后的序列要求严格递增,所以对于每个选进递增子序列的两个数,都要满足(a[r]- a[l] >= r-l), 移项得(a[r] - r >= a[l] - l), 所以对于每个a[i],预处理(a[i] = a[i] - i), 再对处理后的序列求满足条件的最长非递减子序列即可。求最长非递减子序列用O(nlogn)的做法。

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <list>
    #include <map>
    #include <iostream>
    #include <iomanip>
    #include <queue>
    #include <set>
    #include <stack>
    #include <string>
    #include <unordered_map>
    #include <vector>
    #define LL long long
    #define inf 0x3f3f3f3f
    #define INF 0x3f3f3f3f3f3f
    #define PI 3.1415926535898
    #define F first
    #define S second
    #define endl '
    '
    #define lson  rt << 1
    #define rson  rt << 1 | 1
    #define lowbit(x) (x &(-x))
    #define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
    #define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
    #define _per(i, a, b) for (int i = (a); i >= (b); --i)
    using namespace std;
    
    const int maxn = 5e5 + 7;
    const int maxm = 1e3 + 7;
    int n, k;
    int a[maxn];
    vector<int> v;
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	int x;
    	cin >> n >> k;
    	_rep(i, 1, n) cin >> a[i], a[i] -= i;
    	v.push_back(0), a[0] = -inf;
    	_rep(i, 1, k) {
    		cin >> x;
    		v.push_back(x);
    	}
    	v.push_back(n + 1), a[n + 1] = inf;
    	f(i, 1, v.size()) {
    		if (a[v[i]] < a[v[i - 1]]) {
    			cout << -1 << endl;
    			return 0;
    		}
    	}
    	int ans = 0;
    	f(i, 1, v.size()) {
    		vector<int> tmp;
    		int l = v[i - 1] + 1, r = v[i];
    		_rep(j, l, r) {
    			if (a[j] < a[l - 1] || a[j] > a[r]) continue;
    			if (!tmp.size() || a[j] >= tmp[tmp.size() - 1]) tmp.push_back(a[j]);
    			else {
    				int pos = upper_bound(tmp.begin(), tmp.end(), a[j]) - tmp.begin();
    				tmp[pos] = a[j];
    			}
    		}
    		ans += r - l + 1 - tmp.size();
    	}
    	cout << ans << endl;
    
    }
    
  • 相关阅读:
    子信息传递多个参数
    Oracle q' 简化单引号转义
    HTML的target属性中_blank、_self、_parent、_top含义
    数据库设计之“有时不得不违背的第三范式”
    Jquery下的Ajax调试方法
    JQuery.Ajax之错误调试帮助信息
    定时删除数据-用JOB
    数据分析
    机器学习数学基础
    机器学习数学基础
  • 原文地址:https://www.cnblogs.com/hfcdyp/p/13897339.html
Copyright © 2020-2023  润新知