H-Sequence_2020ICPC 江西省大学生程序设计竞赛(重现赛)@Joanh_Lan (nowcoder.com)
题目描述
给定一个包含n个整数的数组a,你要对它执行两种类型的m个操作。1.给定两个整数x,y,将索引x的个数替换为数字y,即ax:=y。2.给定一个整数x,打印a的连续子序列的个数,其最小值为ax。它保证数组a在任何时候都没有重复的值。
输入描述:
第一行包含两个整数n,m(1Sn,mS105),其中n是数组的大小,m是要执行的操作的数量。第二行包含n个整数,第i个整数是ai (1SaiS231-1)然后是m行,依次描述m个你要执行的操作。每行以一个整数optE[1,2]开始,表示要执行的操作类型。如果opt=1,则会出现两个整数x, y (1Sxsn,1Sys231-1),如上所述。如果opt=2,一个整数x (1sxsn)紧随其后,如上所述。
输出描述:
对于类型2的每个操作,在一行上打印一个整数作为答案。
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
示例1
输入
复制
10 5
8 3 6 2 10 9 5 7 1 4
2 2
1 9 11
1 5 12
2 4
1 8 18
输出
复制
4
28
题解:
(反思:写题时越是有思路,越应该仔细推敲,看能不能以更简单的代码实现,本来已经想到二分了,确想了一直及其傻逼的实现,为啥不直接用二分???)!!!
题意很容易理解,看有多少子串最小值是a[p],暴力的解法就是每次向所求的下标左右遍历,直到找到比他小的,这样我们就知道最左和最右的下标l,r,输出(p - l + 1)*(r - l + 1)即可
可是每次遍历的话,时间复杂度肯定会超
所以我们利用线段树可以求每一段最小值,并且可以进行单点修改
那我们如何求左右边界?
利用两次二分,左右check
L,p p,R是最小值是否a[p]
#include
#include
#include
#include
#include
#include
#include