• [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;
    
    }
    
  • 相关阅读:
    SQL Server执行计划的理解
    SQL Server Profiler工具
    利用SQL Profiler处理开销较大的查询
    查询开销
    详解索引连接类型
    详解执行计划
    数据库引擎调整顾问
    six.moves的用法
    ※数据结构※→☆非线性结构(tree)☆============二叉树 顺序存储结构(tree binary sequence)(十九)
    C++ 线程的创建,挂起,唤醒,终止
  • 原文地址:https://www.cnblogs.com/hfcdyp/p/13897339.html
Copyright © 2020-2023  润新知