[ Educational Codeforces Round 65 (Rated for Div. 2)][二分]
You are given an array consisting of nn integers a1,a2,…,ana1,a2,…,an and an integer xx. It is guaranteed that for every ii, 1≤ai≤x1≤ai≤x.
Let's denote a function f(l,r)f(l,r) which erases all values such that l≤ai≤rl≤ai≤r from the array aa and returns the resulting array. For example, if a=[4,1,1,4,5,2,4,3]a=[4,1,1,4,5,2,4,3], then f(2,4)=[1,1,5]f(2,4)=[1,1,5].
Your task is to calculate the number of pairs (l,r)(l,r) such that 1≤l≤r≤x1≤l≤r≤x and f(l,r)f(l,r) is sorted in non-descending order. Note that the empty array is also considered sorted.
The first line contains two integers nn and xx (1≤n,x≤1061≤n,x≤106) — the length of array aa and the upper limit for its elements, respectively.
The second line contains nn integers a1,a2,…ana1,a2,…an (1≤ai≤x1≤ai≤x).
Print the number of pairs 1≤l≤r≤x1≤l≤r≤x such that f(l,r)f(l,r) is sorted in non-descending order.
3 3 2 3 1
4
7 4 1 3 1 2 2 4 3
6
In the first test case correct pairs are (1,1)(1,1), (1,2)(1,2), (1,3)(1,3) and (2,3)(2,3).
In the second test case correct pairs are (1,3)(1,3), (1,4)(1,4), (2,3)(2,3), (2,4)(2,4), (3,3)(3,3) and (3,4)(3,4).
题意:有一个含有n个元素的数组,数组元素的范围是 1<=ai<=x,你可以删除值在(l,r)的元素,问有多少种方案使删除后数组成为非严格单调递增数组
题解:固定左边界L,则右边界呈现单调性,所以可以二分。判断条件为考虑删除(L,R)之后,(1)L左边的呈现非严格单调递增,(2)R右边呈现非严格单调递增,(3)并且原数组中比L左边某一元素大并且在该元素左边的最大值应<=R,预处理一下即可二分
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define debug(x) cout<<"["<<#x<<"]"<<x<<endl; 5 const int maxn=1e6+5; 6 const int inf=1e8; 7 int a[maxn],b[maxn],maxx2; 8 bool check(ll x0,ll len){ 9 if(b[x0-1]>x0+len-1)return false; 10 if(x0+len-1<maxx2)return false; 11 return true; 12 } 13 int main() { 14 int n,x; 15 scanf("%d%d",&n,&x); 16 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 17 int maxx=a[n]; 18 int minn=x; 19 for(int i=n-1;i>=1;i--){ 20 if(maxx>=a[i]){ 21 maxx=a[i]; 22 } 23 else{ 24 minn=min(a[i],minn); 25 } 26 } 27 maxx=a[1]; 28 for(int i=2;i<=n;i++){ 29 if(maxx>a[i]){ 30 b[a[i]]=max(b[a[i]],maxx); 31 maxx2=max(maxx2,a[i]); 32 } 33 else{ 34 maxx=a[i]; 35 } 36 } 37 for(int i=1;i<=x;i++){ 38 b[i]=max(b[i],b[i-1]); 39 } 40 ll aans=0; 41 for(int i=1;i<=minn;i++){ 42 ll l=1; 43 ll r=x-i+1; 44 ll ans=-1; 45 while(l<=r){ 46 ll mid=(l+r)/2; 47 if(check(i,mid)){ 48 ans=mid; 49 r=mid-1; 50 } 51 else{ 52 l=mid+1; 53 } 54 } 55 if(ans!=-1){ 56 aans+=x-(i+ans-1)+1; 57 } 58 } 59 printf("%lld\n",aans); 60 return 0; 61 } 62 63 /* 64 */