0%

Starter189-Sortable Subarrays (Easy/Hard)

思路讲解

就是问可以通过$ A_i=A_i \mod X$ 这个操作变的有序的子串有多少个?

那么注意到那,这个操作没有说那么不可控,其实就是可以变为[ 0,Aimod(Ai/2+1) ][\ 0,A_i \mod (A_i/2+1)\ ] 中的一个。

https://www.codechef.com/viewsolution/1166421088

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
	FOR(i,1,N){
ll idx=-1;
FOR(j,i,N){
ll val=A[j]%(A[j]/2+1);
// #ifdef LOCAL
// debug(A[j]);debug(val);
// #endif
if(val>idx){
++ans;
++idx;
}else if(A[j]>idx){ // we observe sometime we should not make the num modded
idx=A[j]; // such as test case 1
++ans;
}else{
break;
}
}
}

简单就套一个简单的O(n**2)就过了。困难要求线性复杂度,这个就比较难了。

那么我们试过了,双指针是不太能解决,因为左端点的移动不仅有可能造成右端点的变化,还有可能造成里面的变化,当然这个我们只要表征右端点就行了,但是会使得情况很复杂。

唉,读了很多遍题解,发现他应该是藏了一手,有些东西没说清楚。

upjjiupjjiup_j≥j-i \Rightarrow up_j-j \ge -i 因此我们就是要找到第一个不符合这个式子的数字。

不难发现我们可以用单调栈做这个 P5788 【模板】单调栈。

但是光解决上面的这个问题不够呀,所以我们需要一步,就是推导这个如果我不去删这个数,可以得到什么效果?如果说Ai<jiA_i<j-i,那么就不用管了,到头了。upjji+Aiupjji+Aiup_j\ge j-i+A_i \Rightarrow up_j-j\ge -i+A_i,那么我们也可以用一样的方法去解决。

AC代码

https://www.codechef.com/viewsolution/1166421088

加了一个记忆化搜索就好了。

https://www.codechef.com/viewsolution/1166895091

心路历程(WA,TLE,MLE……)

TLE,应该是被卡了。就是像下面这样走有的时候可能会导致退化为线性时间复杂度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FOR(i,1,N){
ll idx=fib[i],lab=idx-i;
while(idx<=N){
//
if(A[idx]<lab){
ans+=idx-i;
break;
}
ll oidx=idx;
idx=seb[idx];
lab=idx-oidx+A[oidx];
if(idx==N){
if(A[idx]<lab){
ans+=idx-i;
}else{
ans+=idx-i+1;
}
break;
}
}
}