洛谷 PP3373【模板】线段树 2
来源:互联网 发布:新手程序员 私活 编辑:程序博客网 时间:2024/06/07 18:43
题目大意:
已知一个N长数列,有M次操作,每次操作有3种:
s=1 将某区间[l,r]每一个数加上x
s=2 将某区间[l,r]每一个数乘上x
s=3 求出某区间[l,r]的总和 mod k。
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=1000,M<=10000
对于100%的数据:N<=100000,M<=100000
(数据已经过加强^_^)
题解:
就是一个线段树+双重lazy的模版:
不过lazy操作要做双重的。
顺序,区间和*乘法lazy+加法lazy
当前区间如果下放乘法lazy,那么他儿子的2个lazy就都要乘上这个lazy,就等于(加法lazy+区间和乘法lazy) 这个乘法lazy,变成分开乘。加法lazy就只需要下传给儿子的加法lazy就可以了。
var cp,rp,tree:array [0..1000001] of int64; sum:array [0..1000001] of int64; i,j,l,n,m,s,x,y:longint; ans,k,z:int64;procedure build(p,l,r:longint);var mid:longint;begin mid:=(l+r) div 2; tree[p]:=(sum[r]-sum[l-1]+k) mod k; rp[p]:=1; if l>=r then exit; build(p*2,l,mid); build(p*2+1,mid+1,r);end;procedure insert(p,l,r,a,b:longint);var mid,i:longint;begin mid:=(l+r) div 2; if (l=a) and (r=b) then begin tree[p * 2]:=(tree[p * 2]*rp[p]+(mid-l+1)*cp[p]) mod k; tree[p*2+1]:=(tree[p*2+1]*rp[p]+(r - mid)*cp[p]) mod k; rp[p * 2]:=rp[p * 2]*rp[p] mod k; rp[p*2+1]:=rp[p*2+1]*rp[p] mod k; cp[p * 2]:=(cp[p * 2]*rp[p]+cp[p]) mod k; cp[p*2+1]:=(cp[p*2+1]*rp[p]+cp[p]) mod k; cp[p]:=0; rp[p]:=1; if s=1 then begin tree[p]:=tree[p]*z mod k; rp[p]:=rp[p]*z mod k; end else begin tree[p]:=(tree[p]+(r-l+1)*z) mod k; cp[p]:=(cp[p]+z) mod k; end; end else begin tree[p * 2]:=(tree[p * 2]*rp[p]+(mid-l+1)*cp[p]) mod k; tree[p*2+1]:=(tree[p*2+1]*rp[p]+(r - mid)*cp[p]) mod k; rp[p * 2]:=rp[p * 2]*rp[p] mod k; rp[p*2+1]:=rp[p*2+1]*rp[p] mod k; cp[p * 2]:=(cp[p * 2]*rp[p]+cp[p]) mod k; cp[p*2+1]:=(cp[p*2+1]*rp[p]+cp[p]) mod k; cp[p]:=0; rp[p]:=1; if b<=mid then insert(p * 2,l,mid,a,b) else if a>mid then insert(p*2+1,mid+1,r,a,b) else begin insert(p * 2,l,mid,a,mid); insert(p*2+1,mid+1,r,mid+1,b); end; tree[p]:=(tree[p * 2]+tree[p*2+1]) mod k; end;end;procedure count(p,l,r,a,b:longint);var mid,i:longint;begin mid:=(l+r) div 2; if (l=a) and (r=b) then ans:=(ans+tree[p]) mod k else begin tree[p * 2]:=(tree[p * 2]*rp[p]+(mid-l+1)*cp[p]) mod k; tree[p*2+1]:=(tree[p*2+1]*rp[p]+(r - mid)*cp[p]) mod k; rp[p * 2]:=rp[p * 2]*rp[p] mod k; rp[p*2+1]:=rp[p*2+1]*rp[p] mod k; cp[p * 2]:=(cp[p * 2]*rp[p]+cp[p]) mod k; cp[p*2+1]:=(cp[p*2+1]*rp[p]+cp[p]) mod k; cp[p]:=0; rp[p]:=1; if b<=mid then count(p * 2,l,mid,a,b) else if a>mid then count(p*2+1,mid+1,r,a,b) else begin count(p * 2,l,mid,a,mid); count(p*2+1,mid+1,r,mid+1,b); end; end;end;begin readln(n,m,k); for i:=1 to n do begin read(sum[i]); sum[i]:=(sum[i]+sum[i-1]) mod k; end; build(1,1,n); for i:=1 to m do begin read(s); if (s=1) or (s=2) then begin read(x,y,z); insert(1,1,n,x,y); end else if s=3 then begin ans:=0; read(x,y); count(1,1,n,x,y); writeln(ans); end; readln; end;end.
1 0
- 洛谷 PP3373【模板】线段树 2
- 线段树模板2
- 洛谷 P3373 【模板】线段树 2 (线段树)
- 洛谷P3373 【模板】线段树2
- 【模板】线段树 洛谷 3372 线段树
- 洛谷 P3372 线段树模板
- ACM 线段树模板(模板)
- 洛谷 3372_【模板】线段树 1_线段树
- 【洛谷】P3372线段树1 线段树模板
- 【洛谷1592】【模板】template 线段树 线段树裸题
- [luogu3373][模板]线段树 2(线段树)
- 【洛谷P3372】【模板】线段树 1
- 洛谷P3374模板线段树1
- 洛谷3372[模板]线段树1
- 洛谷 P3372【模板】线段树 1
- 洛谷P3372 【模板】线段树 1
- 洛谷 P3372 【模板】线段树 1
- 【洛谷P3372】【模板】线段树1
- mac安装Redis,Redis Desktop Manager
- 二分查找
- 块级元素及行内元素
- SpringBoot -- 集成Elasticsearch
- 构造函数
- 洛谷 PP3373【模板】线段树 2
- HTTP权威指南读书笔记一:HTTP简介
- Sum Problem
- 竞赛图结论学习小结
- 控制对文件的访问
- struts中出现Java.lang.NoClassDefFoundError解决办法
- 关于des加密的神坑
- Android 申请运行时权限 以camera为例
- 你可能不知道的5中CSS和JS的交互方式