赞
踩
You are given an array of n integers a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1,a2,...,an, and a a a set b b b of k k k distinct integers from 1 1 1 to n n n.
In one operation, you may choose two integers i i i and x x x ( 1 ≤ i ≤ n 1≤i≤n 1≤i≤n, x x x can be any integer) and assign a i : = x a_i:=x ai:=x. This operation can be done only if i i i does not belong to the set b b b.
Calculate the minimum number of operations you should perform so the array a is increasing (that is, a 1 < a 2 < a 3 < ⋯ < a n a_1<a_2<a_3<⋯<a_n a1<a2<a3<⋯<an), or report that it is impossible.
The first line contains two integers n n n and k k k ( 1 ≤ n ≤ 5 ⋅ 1 0 5 , 0 ≤ k ≤ n 1≤n≤5⋅10^5, 0≤k≤n 1≤n≤5⋅105,0≤k≤n) — the size of the array a and the set b, respectively.
The second line contains n n n integers a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1,a2,...,an ( 1 ≤ a i ≤ 1 0 9 1≤a_i≤10^9 1≤ai≤109).
Then, if k ≠ 0 k≠0 k=0, the third line follows, containing k k k integers b 1 , b 2 , . . . , b k b_1, b_2, ..., b_k b1,b2,...,bk ( 1 ≤ b 1 < b 2 < ⋯ < b k ≤ n 1≤b_1<b_2<⋯<b_k≤n 1≤b1<b2<⋯<bk≤n). If k = 0 k=0 k=0, this line is skipped.
If it is impossible to make the array a increasing using the given operations, print − 1 −1 −1.
Otherwise, print one integer — the minimum number of operations you have to perform.
7 2
1 2 1 1 3 5 1
3 5
4
有一个数组a,数组某些位置的数不可操作,其余位置的数可以进行操作,将其赋为任意值。求最少的操作次数,使数组a为升序序列,或者输出无解。
判断无解:因为要求序列a严格递增,所以若 两个相邻的不可动的位置的值的差 小于 他们之间的距离,则无解。即 a p o s 2 − a p o s 1 < p o s 2 − p o s 1 a_{pos2}-a_{pos1} < pos2-pos1 apos2−apos1<pos2−pos1时无解( p o s 1 < p o s 2 pos1<pos2 pos1<pos2)。
最少操作次数:有些位置的数不能更改,则这些位置将数组分割为若干段,取其中连续的一段为,
d
1
,
d
2
,
.
.
.
d
k
d_1,d_2,...d_k
d1,d2,...dk,其中
d
1
,
d
k
d_1,d_k
d1,dk是固定的(为方便计算,可以另
a
0
=
−
I
N
F
,
a
n
+
1
=
I
N
F
a_0=-INF,a_{n+1}=INF
a0=−INF,an+1=INF)。
由样例可知单纯的求最长上升子序列是不行的。考虑转化一下,设
e
1
=
0
,
e
i
=
d
i
−
d
1
−
(
i
−
1
)
e_1=0,e_i=d_i-d_1-(i-1)
e1=0,ei=di−d1−(i−1),e代表若当前位置的数不变,
e
i
e_i
ei与
e
1
e_1
e1的最小差值。(因为首位不可变,所以当
e
i
<
0
e_i<0
ei<0时,可以考虑将其赋为INF)。
现在问题就转化为求以
e
k
e_k
ek结尾的,最长不降子序列的长度len。则 区间长度-len 为另当前子段单调递增所需要的最少操作次数。
所有子段的结果相加,即为所求。
#include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<algorithm> #include<cstring> #include<map> #include<vector> #include<queue> #include<iterator> #include<string> #define dbg(x) cout<<#x<<" = "<<x<<endl; #define INF 0x3f3f3f3f #define LLINF 0x3f3f3f3f3f3f3f3f #define eps 1e-6 using namespace std; typedef long long LL; typedef pair<int, int> P; const int maxn = 500100; const int mod = 998244353; int top, a[maxn], b[maxn], c[maxn]; int main() { int n, m, i, j, k, ans = 0, pos; scanf("%d %d", &n, &m); a[0] = -INF, a[n+1] = INF; b[0] = b[n+1] = 1; for(i=1;i<=n;i++)scanf("%d", &a[i]); for(i=1;i<=m;i++){ scanf("%d", &j); b[j] = 1; } i = 0; while(i<=n){ for(j=i+1;b[j]!=1;j++); if(a[j] < a[i]+(j-i))break; top = 0; c[top++] = 0; for(k=i+1;k<j;k++){ if(a[k]-a[i]-(k-i) < 0)a[k] = INF; else a[k] = a[k] - a[i]-(k-i); if(a[k] >= c[top-1])c[top++] = a[k]; else{ pos = upper_bound(c, c+top, a[k])-c; c[pos] = a[k]; } } pos = upper_bound(c, c+top, a[j]-a[i]-(j-i))-c; ans += j-i-pos; i = j; } if(i<=n)puts("-1"); else printf("%d\n", ans); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。