BZOJ 1798-维护序列seq(线段树区间更新)
来源:互联网 发布:电脑视频录像软件 编辑:程序博客网 时间:2024/05/16 13:38
1798: [Ahoi2009]Seq 维护序列seq
Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 6582 Solved: 2345
[Submit][Status][Discuss]
Description
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。
Input
第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。
Output
对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
Sample Input
7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7
Sample Output
2
35
8
35
8
HINT
线段树区间更新模板题,唯一难点在于乘除先后顺序的处理,这里设定优先级,先乘后加(只是相对的),
#include<map>#include<stack>#include<queue>#include<vector>#include<math.h>#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include<algorithm>using namespace std;typedef long long ll;#define inf 10000000#define maxn 800005#define eps 1e-10ll sum[maxn],add[maxn],mul[maxn];void build(ll l,ll r,ll id,ll p){if(l==r){mul[id]=1;add[id]=0;scanf("%lld",&sum[id]);return;}ll m=(l+r)/2;build(l,m,id*2,p);build(m+1,r,id*2+1,p);sum[id]=(sum[id*2]+sum[id*2+1])%p;mul[id]=1;add[id]=0;}void pushdown(ll id,ll l,ll r,ll p){mul[id*2]*=mul[id];mul[id*2]%=p;mul[id*2+1]*=mul[id];mul[id*2+1]%=p;add[id*2]*=mul[id];add[id*2]%=p;add[id*2+1]*=mul[id];add[id*2+1]%=p;add[id*2]+=add[id];add[id*2]%=p;add[id*2+1]+=add[id];add[id*2+1]%=p;sum[id]=sum[id]*mul[id]+(r-l+1)*add[id];sum[id]%=p;add[id]=0;mul[id]=1;}void updata1(ll id,ll L,ll R,ll l, ll r,ll x,ll p){pushdown(id,L,R,p);if(l>R || r<L)return;if(l<=L && r>=R){add[id]+=x;pushdown(id,L,R,p);return;}ll m=(L+R)/2;//if(l<=m)updata1(id*2,L,m,l,r,x,p);//if(r>m)updata1(id*2+1,m+1,R,l,r,x,p);sum[id]=(sum[id*2]+sum[id*2+1])%p;}void updata2(ll id,ll L,ll R,ll l, ll r,ll x,ll p){pushdown(id,L,R,p);if(l>R || r<L)return;if(l<=L && r>=R){mul[id]*=x;pushdown(id,L,R,p);return;}ll m=(L+R)/2;//if(l<=m)updata2(id*2,L,m,l,r,x,p);//if(r>m)updata2(id*2+1,m+1,R,l,r,x,p);sum[id]=(sum[id*2]+sum[id*2+1])%p;}ll query(ll id,ll L,ll R,ll l,ll r,ll p){pushdown(id,L,R,p);ll ans=0;if(l>R || r<L)return 0;if(l<=L && R<=r)return sum[id]%p;ll m=(L+R)/2;//if(l<=m)ans=(ans+query(id*2,L,m,l,r,p))%p;//if(r>m)ans=(ans+query(id*2+1,m+1,R,l,r,p))%p;sum[id]=(sum[id*2]+sum[id*2+1])%p;return ans%p;}int main(void){ll n,q,i,j,x,y,z,w,p;scanf("%lld%lld",&n,&p);build(1,n,1,p);scanf("%lld",&q);while(q--){scanf("%lld",&w);if(w==1){scanf("%lld%lld%lld",&x,&y,&z);updata2(1,1,n,x,y,z,p);}if(w==2){scanf("%lld%lld%lld",&x,&y,&z);updata1(1,1,n,x,y,z,p);}if(w==3){scanf("%lld%lld",&x,&y);printf("%lld\n",query(1,1,n,x,y,p)%p);}}return 0;}
阅读全文
0 0
- BZOJ 1798-维护序列seq(线段树区间更新)
- bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq|线段树
- 【BZOJ】1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq 线段树题解
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树模板
- bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树
- bzoj 1798 维护序列 seq (线段树)
- 【BZOJ/Luogu】1798/P3373 [Ahoi2009]Seq 维护序列seq/【模板】线段树 2 区间加、乘线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树乘法加法的混合操作)
- BZOJ 题目1798: [Ahoi2009]Seq 维护序列seq(双标记线段树)
- BZOJ 1798 AHOI2009 Seq 维护序列 线段树
- BZOJ 1798 [Ahoi2009]维护序列seq (线段树)
- 运维工具之轻量级自动化运维工具Fabric源码安装
- iOS 删除系统自带的tabbar
- java list 数据去重
- 二叉树遍历
- 提升编码能力,阅读代码
- BZOJ 1798-维护序列seq(线段树区间更新)
- 文章标题
- python3.6下安装selenium
- linux之压缩文件,查看压缩文件,解压文件的操作命令
- 卡方检验 CHI-square Test
- Spark——性能调优——执行模型与分区
- jilu
- 4、Angular-Ui Router URL路由(完结篇)
- Struts2-----基本项目创建