首先,我們來理一遍題意,第一行輸入n是整數序列長度,且整數值小於N,第二行為整數序列A1~An,f(x)是序列中小於等於x的整數里最大的數的下標。我們需要計算的是sum=f(0)+f(1)+...+f(N-1)。
本來沒什么思路,但一看到樣例解釋,這不就是前綴和+差分嘛!
用樣例1來解釋一下思路:
思路:根據題意,當x<2時,序列中小於等於x的最大數是0,下標為0,即f(0),f(1)都為0,當2<=x<5時,序列中小於等於x的最大數是2,下標為1,即f(2)~f(4)都為1,則可知當x取[A[i],A[i+1])時,序列中小於等於x的最大數是A[i],下標為i,即f(A[i])~f(A[i+1]-1)都等於i。
因為f(x)某一段范圍內的值都相等,且每一段范圍內f(x)的值比前一段范圍內的都要大1。所以我們可以讓f(x)在范圍[A[1],N-1]的值為1,后面每段范圍的值在原基礎上+1,即每段范圍[A[i],N-1]的值++,由此想到可以用差分和前綴和的方法。
開始解題:我們設置一個差分數組dif,dif[i]表示的是f(i)-f(i-1),現在要使下標為[2,9]的f(x)值都要+1,那么對於下標為[2,9]的元素來說,它們的差分不會改變,因為大家都加了1,所以對一個范圍內的值操作,影響的只是范圍內與范圍外的值的差分,即范圍的臨界的差分。所以dif[2]++即可。同理,我們要使下標為[5,9]的f(x)值都要+1,dif[5]++即可。所以最后,我們只做了dif[2]++,dif[5]++,dif[8]++的工作,從而求出了f(x)的差分數組。
根據定理:f(x)=dif[1]+dif[2]+...+dif[x]=f(x)-f(0),最后再求f(x)的和即可。
代碼如下:
思路來源於:https://www.cnblogs.com/yongcheng137blogs/p/15412952.html
202109-2 非零段划分也是這個方法