题目描述
给定一个长度 n 的序列 1,…,a1,…,an,需要进行 m 次操作,操作共有三种类型:
操作 1:给定 l,r,x,先新建一个数组 b 满足 bi=ai,之后将 ax,…,ax+r−l 同时修改为 bl,…,br;
操作 2:给定 l,r,将al,…,ar 同时修改为除以 22 下取整后的值;
操作 3:给定 l,r,求 al,…,ar 的和。
输入格式
第一行一个整数n。
接下来一行n 个整数表示序列1,…,a1,…,an。
接下来一行一个整数 m。
接下来m 行,每行表示一个操作:
1 l r x
表示操作 1;
2 l r
表示操作 2;
3 l r
表示操作 3。
输出格式
共m 行,每行一个整数,表示每个操作的答案。
输入输出样例
输入 #1
10 6 3 5 93 89 1 1 3 39 3804 3800 3800 3791 3804 3807 3803 3720 83 93 90 121 87 86 81 110 298 291 302 383 298 296 303 266 15768 15760 15818 15836 15768 15773 15773 15822 204761 204753 204692 204781 204765 204765 204762 204678
输出 #1
3805 85 299 15769 204763 93
说明/提示
Idea:nzhtl1477,Solution:ccz181078,Code:ccz181078,Data:ccz181078
样例解释:
在强制在线加密前,样例输入为:
10 6
3 5 93 89 1 1 3 39
1 5 5 18 1 2 6 85
6 8 15 44 2 3 4 59
1 8 5 84 1 3 4 33
1 9 83 69 1 4 4 87
2 10 79 54 6 6 1 93
对于 100%100% 的数据,满足:
1≤n≤106
1≤m≤3×105
对于 1≤i≤m:
1≤Li≤Ri≤n
1≤ai≤106
1≤bi≤106
1≤li≤ri≤i
1≤Xi≤n
1≤xi≤106。
一血纪念。
题目很抽象,大概意思是,给出一个操作序列 (Li,Ri,v),v 是幺半群中的元素。并且给出运算 ⊕⊕,每次在操作序列末尾插入,或者询问给出 l,r,x,按顺序遍历 [l,r] 中的操作,若 i≤x≤Ri 就把答案 ⊕v,否则答案不变。强制在线。
考虑在线构建操作序列的线段树,每次插入操作需要建立线段树上的若干节点。
考虑建立的节点为自底向上的一条右链,那么注意到这里是可以对每个节点 pushup 的,此处的时间复杂度仍然为 O(nlogn)。
那么问题就是在线段树上分解区间,对于分解出的区间,找到 �x 所属的区间,即找到前驱。
考虑分散层叠的思想,在父节点保存两个子节点的归并序列并且指向子节点的序列的位置。那么只用在根节点二分一次,此后每次都可以直接定位到子节点的序列。对每个根进行定位,考虑从大到小维护 2k 的分散层叠,每次选取 1441 和 1221 的点混合。
这部分是口胡,代码待补。