1798: [Ahoi2009]Seq 维护序列seq

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 7773  Solved: 2792
[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

Sample Output

2
35
8

HINT

【样例说明】

初始时数列为(1,2,3,4,5,6,7)。
经过第1次操作后,数列为(1,10,15,20,25,6,7)。
对第2次操作,和为10+15+20=45,模43的结果是2。
经过第3次操作后,数列为(1,10,24,29,34,15,16}
对第4次操作,和为1+10+24=35,模43的结果是35。
对第5次操作,和为29+34+15+16=94,模43的结果是8。

测试数据规模如下表所示

数据编号 1 2 3 4 5 6 7 8 9 10
N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

Source

 
实现代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int M = 2e5+;
ll sum[M<<],add[M<<],mul[M<<],md; void pushup(int rt){
sum[rt] = (sum[rt<<] + sum[rt<<|])%md;
} void pushdown(int m,int rt){
add[rt<<] = (add[rt<<]*mul[rt] + add[rt])%md;
add[rt<<|] = (add[rt<<|]*mul[rt]+add[rt])%md;
mul[rt<<] = mul[rt<<]*mul[rt]%md;
mul[rt<<|] = mul[rt<<|]*mul[rt]%md;
sum[rt<<] = (sum[rt<<]*mul[rt] + add[rt]*(m-(m>>)))%md;
sum[rt<<|] = (sum[rt<<|]*mul[rt]+add[rt]*(m>>))%md;
add[rt] = ; mul[rt] = ;
} void build(int l,int r,int rt){
add[rt] = ;mul[rt] = ;
if(l==r){
scanf("%lld",&sum[rt]);
return;
}
int m = (l + r) >> ;
build(lson);
build(rson);
pushup(rt);
} void update(int L,int R,int c,int v,int l,int r,int rt){
if(L <= l&&R >= r){
if(v==){
sum[rt] = sum[rt]*c%md;
add[rt] = add[rt]*c%md;
mul[rt] = mul[rt]*c%md;
}
else{
sum[rt] = (sum[rt] + (ll)c*(r-l+))%md;
add[rt] = (add[rt]+c)%md;
}
return;
}
pushdown(r-l+,rt);
int m = (l + r) >> ;
if(L <= m) update(L,R,c,v,lson);
if(R > m) update(L,R,c,v,rson);
pushup(rt);
} ll query(int L,int R,int l,int r,int rt){
if(L <= l&&R >= r){
return sum[rt]%md;
}
pushdown(r-l+,rt);
ll ret = ;
int m = (l + r) >> ;
if(L <= m) ret = (ret+query(L,R,lson))%md;
if(R > m) ret = (ret+query(L,R,rson))%md;
return ret;
} int main()
{
int n,q,a,c,b,d;
scanf("%d %lld",&n,&md);
build(,n,);
scanf("%d",&q);
while(q--){
scanf("%d",&a);
if(a==){
scanf("%d %d %d",&b,&c,&d);
update(b,c,d,,,n,);
}
else if(a==){
scanf("%d %d %d",&b,&c,&d);
update(b,c,d,,,n,);
}
else{
scanf("%d%d",&b,&c);
printf("%lld\n",query(b,c,,n,));
}
}
}

bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)的更多相关文章

  1. 【BZOJ1798】【AHOI2009】维护序列(线段树)

    题目链接 题解 这不就是luogu的线段树2的板子吗.... 没有任何的区别... 上代码吧... #include<iostream> #include<cstdio> #i ...

  2. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

  3. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  4. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  5. 1798: [Ahoi2009]Seq 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 2930  Solved: 1087[Submit ...

  6. BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5504  Solved: 1937[Submit ...

  7. BZOJ_1798_[AHOI2009]维护序列_线段树

    BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...

  8. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  9. 【BZOJ】1798: [Ahoi2009]Seq 维护序列seq 线段树多标记(区间加+区间乘)

    [题意]给定序列,支持区间加和区间乘,查询区间和取模.n<=10^5. [算法]线段树 [题解]线段树多重标记要考虑标记与标记之间的相互影响. 对于sum*b+a,+c直接加上即可. *c后就是 ...

随机推荐

  1. Python3.2-re模块之常用正则记录

    python的re模块是个很好的模块,这里简单记录下自己编写的几个有用的正则: 1:邮箱匹配: gReMailbox = re.compile(r'([\w\.\-+]+@[\w\-]+(?:\.[\ ...

  2. gitlab webhook php exec 调用 shell 脚本。shell 脚本中调用 git pull 命令无法执行。

    情况如下: 我在ubuntu server 14.04 上面安装了gitlab,来托管项目代码.然后想通过gitlab的web hook 功能来做测试服务器代码自动化更新代码功能.现在遇到一个问题:就 ...

  3. js中数组的使用

    使用js时候,很多情况下要使用数组.就写写数组中一些常用的方法. js中定义一个数组,一般有以下2种方法. 1. var arr = new Array(3); // 声明数组有3个元素 arr[0] ...

  4. mfc c++字符串类与 流输出

    一.命名空间 所谓命名空间(namespace),是指标识符的各种可见范围.C++标准程序库中的所有标识符都被定义于一个名为std的命名空间(namespace)中.而我们要使用的string类也是一 ...

  5. Nginx日常报错处理总结

    在Nginx错误日志中,有大量的下列信息: Upstream timed out (110: Connection timed out) while reading response header f ...

  6. dotnet core webapi 发布部署到docker的步骤

    1. 创建web api项目,编译并测试成功 2. 在项目的根目录添加Dockerfile文件,注意:Dockerfile文件名区分大小写 文件内容如下 # 基于microsoft/dotnet:la ...

  7. Vue.js动态组件

    动态组件: 1.定义: 几个组件放在同一个挂载点下,然后根据父组件的某个变量来决定显示哪个,或者都不显示. 2.动态切换原理: 在挂载点使用<component>标签,然后使用v-bind ...

  8. Django实现websocket完成实时通讯、聊天室、在线客服等

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

  9. linux之grep 基础

    第一章 -a    将binary文件以text文件的方式搜寻数据-c    只输出匹配行的计数,计算找到匹配的次数-I(大写i)    不区分大小写(只适合用于单字符)-h    查询多文件时不显示 ...

  10. Windows Defender还原误删文件

    Win 10 新版本的Windows Defender隔离/删除的文件没有还原的选项,导致被误删的文件无法在威胁记录中恢复.经过尝试发现可以通过修改注册表添加 “还原” 选项 打开注册表,找到 HKE ...