思路讲解
求解右边第一个大于自己的数的下标。
AC代码
https://www.luogu.com.cn/record/220790487
1 | // Problem: P5788 【模板】单调栈 |
求解右边第一个大于自己的数的下标。
https://www.luogu.com.cn/record/220790487
1 | // Problem: P5788 【模板】单调栈 |
就是问可以通过$ A_i=A_i \mod X$ 这个操作变的有序的子串有多少个?
那么注意到那,这个操作没有说那么不可控,其实就是可以变为[ 0,Aimod(Ai/2+1) ] 中的一个。
https://www.codechef.com/viewsolution/1166421088
1 | FOR(i,1,N){ |
简单就套一个简单的O(n**2)就过了。困难要求线性复杂度,这个就比较难了。
那么我们试过了,双指针是不太能解决,因为左端点的移动不仅有可能造成右端点的变化,还有可能造成里面的变化,当然这个我们只要表征右端点就行了,但是会使得情况很复杂。
唉,读了很多遍题解,发现他应该是藏了一手,有些东西没说清楚。
upj≥j−i⇒upj−j≥−i 因此我们就是要找到第一个不符合这个式子的数字。
不难发现我们可以用单调栈做这个 P5788 【模板】单调栈。
但是光解决上面的这个问题不够呀,所以我们需要一步,就是推导这个如果我不去删这个数,可以得到什么效果?如果说Ai<j−i,那么就不用管了,到头了。upj≥j−i+Ai⇒upj−j≥−i+Ai,那么我们也可以用一样的方法去解决。
https://www.codechef.com/viewsolution/1166421088
1 | // Problem: Sortable Subarrays (Easy) |
加了一个记忆化搜索就好了。
https://www.codechef.com/viewsolution/1166895091
1 | // Problem: Sortable Subarrays (Hard) |
TLE,应该是被卡了。就是像下面这样走有的时候可能会导致退化为线性时间复杂度。
1 | FOR(i,1,N){ |
1 | // Problem: Sortable Subarrays (Hard) |
https://www.codechef.com/viewsolution/1165824691
简单的后缀最大判断。
困难版的题意稍微有点难懂,但是总的来说就是你不是找出来一个M吗,这个最大格挡序列可不可以包含i?
那么代码分析我放在这个链接里了,反正都是chinglish,都是读的懂的。
https://www.codechef.com/viewsolution/1166105552
那么正向的贪心操作怎么样复制到这个逆向那?我认为这个是这道题目比较值得学习的点。
1 | ROF(i,N,1){ |
https://www.codechef.com/viewsolution/1165824691
1 | // Problem: Parry It! (Easy) 招架!(简单) |
https://www.codechef.com/viewsolution/1166105552
1 | // Problem: Parry It! (Hard) 招架!(困难) |
codeChef题目可以看viewsolution,就是下面这个链接
1 | inline ll diff(ll a,ll b){ |
https://www.codechef.com/viewsolution/1165814370
1 | // Problem: Subsequence Sort |
行上面反转,使列上面为排列。
注意到,可以对称的操作,反转1,i,使得 i 为首,再反转N-i+1,N,
1 | // 第一阶段操作 |
1 | #include <iostream> |