lg4891题解

事实上这道题并不需要使用分块即可做出。
定义数组\(d\):当\(b_i>c_i,d_i=0\)否则\(d_i=1\)
容易发现\(d_i\)只会变化\(O(n)\)次,因为变大B数组的一个数会让最多一个\(1->0\),变大\(A\)数组中的一个数会让若干个\(0->1\)
考虑1~n中每一个下标\(i\),显然它经历的\(0->1\)的次数和\(1->0\)的次数的量级是相同的。
\(1->0\)的次数总共只有\(O(n)\)次,所以\(0->1\)的次数也只有\(O(n)\)次。
考虑维护4个线段树:第一个维护\(b\)中每个节点的维护区间最小值。
第二个线段树中,对于每个下标\(i\),如果\(d_i=1\),则线段树中该点值为\(1\),否则为\(c_i\),维护这些值的乘积,每个节点还维护它管辖的区间的值的乘积和它区间内\(d_i=0\)的值的数量。
第三个线段树中,对于每个下标\(i\),如果\(d_i=0\),则线段树中该点值为\(1\),否则为\(b_i\),维护这些值的乘积,每个节点还维护它管辖的区间的值的乘积和它区间内\(d_i=1\)的值的数量。
第四个线段树维护\(c\)
显然答案为第二个线段树的根节点的值乘以第三个线段树的根节点的值。
在修改时,如果修改\(a\)数组,由于\(a\)数组是单调递增的,且修改后值会变大,所以这相当于把\(c_{x...n}\)\(y\)取最大值。
在第四个线段树上二分找到最后一个位置\(p\)使得\(c_p<y\),把\(c_{x...p}\)赋值为\(y\)即可。
在第一个线段树递归上找到所有\(<y\)的位置,时间复杂度为位置个数到根节点的链并的,为\(位置个数*log_2n\)
根据这些位置,在第二/三个线段树上修改它管辖的区间的值的乘积和它区间内\(d_i=x\)的值的数量。
然后把剩下第2个线段树上定位到的每个区间的乘积修改为\(y^{它区间d_i=0的值的个数}\),用快速幂计算。
这个修改对第三个线段树没有影响,对于第二个线段树上的每个节点。
如果修改b数组,那么只需要找到\(a_x\),和y比较,在第1,2,3个线段树上单点修改即可。
时间复杂度瓶颈在快速幂,为\(O(n\log_2^2n)\)

posted @ 2023-01-03 16:04  celerity1  阅读(23)  评论(0)    收藏  举报