退役了,想起了在役做过的两道精妙的小题,溜回机房写题解/kel
第一道
题意:给定长度为n的序列B_I,初始c为0,顺序i为1~n执行 c=max(0,min(Max,c+B_i)),Max会更改,B_I会更改,c更不更改无所谓,每次更改后求出c执行后的值,权值范围都是-1e9~1e9,长度和操作数5e5级别
神仙yww给出了神仙做法
考虑给定c和线段树上的一个区间[l,r],我们判断c经过l,r后变成什么
取出[mid+1,r],判断0和Max经过后是否会变成同一个数,很好判断
如果会变成同一个数,直接随便一个数进入[mid+1,r],毕竟没影响
如果不会,那么对于[mid+1,r],我们很好求出每个数经过它后会变成什么
只要维护好最值子段和,前缀和,后缀和即可,于是这时进入[l,mid]
这个做法也可以在log的时间内求出经过序列的任意一个区间后会变成什么
时间复杂度:
O
(
M
l
o
g
2
n
)
O(Mlog_2n)
O(Mlog2n)
第二道
给出n*n的矩阵,对于子矩形(a,b)-(c,d),定义周长为2(b-a+1)+2(d-c+1),面积为其中Ai,j的和,问面积比周长的最大值,n<=500,权值1e9级别
实际实现的时候要用long double,要不精度不太够?
固定a,b很好求答案,二分即可
如果我们对所有(a,b)对random_shuffle,当且仅当当前答案大于之前答案才进行二分求当前答案
那么复杂度:
O
(
n
3
+
l
n
(
n
2
)
∗
l
o
g
A
n
s
∗
n
)
O(n^3+ln(n^2)*logAns*n)
O(n3+ln(n2)∗logAns∗n)