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

 
线段树乘法模板
乘法的难点在于考虑先加再乘还是先乘再加

当lazytage下标传递的时候,我们需要考虑,是先加再乘还是先乘再加。我们只需要对lazytage做这样一个处理。

lazytage分为两种,分别是加法的plz和乘法的mlz。

mlz很简单处理,pushdown时直接*父亲的就可以了,那么加法呢?

我们需要把原先的plz*父亲的mlz再加上父亲的plz.

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define MAXN 100010
#define INF 10000009
#define MOD 10000007
#define LL long long
#define in(a) a=read()
#define REP(i,k,n) for(long long i=k;i<=n;i++)
#define DREP(i,k,n) for(long long i=k;i>=n;i--)
#define cl(a) memset(a,0,sizeof(a))
inline long long read(){
long long x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
inline void out(long long x){
if(x<) putchar('-'),x=-x;
if(x>) out(x/);
putchar(x%+'');
}
long long n,m,p;
long long input[MAXN];
struct node{
long long l,r;
long long sum,mlz,plz;
}tree[*MAXN];
inline void build(long long i,long long l,long long r){
tree[i].l=l;
tree[i].r=r;
tree[i].mlz=;
if(l==r){
tree[i].sum=input[l]%p;
return ;
}
long long mid=(l+r)>>;
build(i<<,l,mid);
build(i<<|,mid+,r);
tree[i].sum=(tree[i<<].sum+tree[i<<|].sum)%p;
return ;
}
inline void pushdown(long long i){
long long k1=tree[i].mlz,k2=tree[i].plz;
tree[i<<].sum=(tree[i<<].sum*k1+k2*(tree[i<<].r-tree[i<<].l+))%p;
tree[i<<|].sum=(tree[i<<|].sum*k1+k2*(tree[i<<|].r-tree[i<<|].l+))%p;
tree[i<<].mlz=(tree[i<<].mlz*k1)%p;
tree[i<<|].mlz=(tree[i<<|].mlz*k1)%p;
tree[i<<].plz=(tree[i<<].plz*k1+k2)%p;
tree[i<<|].plz=(tree[i<<|].plz*k1+k2)%p;
tree[i].plz=;
tree[i].mlz=;
return ;
}
inline void mul(long long i,long long l,long long r,long long k){
if(tree[i].r<l || tree[i].l>r) return ;
if(tree[i].l>=l && tree[i].r<=r){
tree[i].sum=(tree[i].sum*k)%p;
tree[i].mlz=(tree[i].mlz*k)%p;
tree[i].plz=(tree[i].plz*k)%p;
return ;
}
pushdown(i);
if(tree[i<<].r>=l) mul(i<<,l,r,k);
if(tree[i<<|].l<=r) mul(i<<|,l,r,k);
tree[i].sum=(tree[i<<].sum+tree[i<<|].sum)%p;
return ;
}
inline void add(long long i,long long l,long long r,long long k){
if(tree[i].r<l || tree[i].l>r) return ;
if(tree[i].l>=l && tree[i].r<=r){
tree[i].sum+=((tree[i].r-tree[i].l+)*k)%p;
tree[i].plz=(tree[i].plz+k)%p;
return ;
}
pushdown(i);
if(tree[i<<].r>=l) add(i<<,l,r,k);
if(tree[i<<|].l<=r) add(i<<|,l,r,k);
tree[i].sum=(tree[i<<].sum+tree[i<<|].sum)%p;
return ;
}
inline long long search(long long i,long long l,long long r){
if(tree[i].r<l || tree[i].l>r) return ;
if(tree[i].l>=l && tree[i].r<=r)
return tree[i].sum;
pushdown(i);
long long sum=;
if(tree[i<<].r>=l) sum+=search(i<<,l,r)%p;
if(tree[i<<|].l<=r) sum+=search(i<<|,l,r)%p;
return sum%p;
}
int main(){
in(n);in(p);
REP(i,,n) in(input[i]);
build(,,n);
in(m);
REP(i,,m){
long long fl,a,b,c;
in(fl);
if(fl==){
in(a);in(b);in(c);
c%=p;
mul(,a,b,c);
}
if(fl==){
in(a);in(b);in(c);
c%=p;
add(,a,b,c);
}
if(fl==){
in(a);in(b);
printf("%lld\n",search(,a,b));
}
}
return ;
}
/*
5 4 1000
1 2 3 4 5
3 1 5
2 1 5 1
1 1 5 2 3 1 5
*/

bzoj1798 维护序列的更多相关文章

  1. BZOJ1798 维护序列seq

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

  2. 【双标记线段树】bzoj1798维护序列seq

    一.题目 描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列 ...

  3. p2023&bzoj1798 维护序列

    传送门(洛谷) 传送门(bzoj) 题目 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全 ...

  4. bzoj1798维护序列

    题目链接 暴力数据结构之线段树$qwq$ 裸题直接敲板子 忘了啥时候写的了$qwq$ 直接上代码吧 /************************************************* ...

  5. BZOJ-1798 维护序列

    线段树.支持区间加.区间乘.区间查询和. 标记下移还有取模要注意. var n,p,q,i,s,t:longint; a:int64; num,n1,n2,n3:array[0..500000] of ...

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

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

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

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

  8. bzoj 维护序列seq(双标记线段树)

    Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 4184  Solved: 1518[Submit][Status][Discus ...

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

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

随机推荐

  1. sqlite3使用简介

    sqlite3使用简介 一.使用流程 要使用sqlite,需要从sqlite官网下载到三个文件,分别为sqlite3.lib,sqlite3.dll,sqlite3.h,然后再在自己的工程中配置好头文 ...

  2. nfs挂载无法卸载

    故障现象:今天发现服务器的upload负载很高,到18左右,同时df查看磁盘命令卡住 用top\vmstat\iostat查看并未发现可以服务或进程. 上网查发现可能是nfs问题. 卸载nfs挂载的方 ...

  3. mysql视图学习总结(转)

    一.使用视图的理由是什么?1.安全性.一般是这样做的:创建一个视图,定义好该视图所操作的数据.之后将用户权限与视图绑定.这样的方式是使用到 了一个特性:grant语句可以针对视图进行授予权限.2.查询 ...

  4. BeanUtils封装对象时一直提示ClassNotFoundException:org.apache.commons.beanutils.BeanUtils

    导包明明正确了,依赖包也全都导对了,还是出错. 困扰了3天. 后来看到这篇博文,https://blog.csdn.net/yanshaoshuai/article/details/81624890 ...

  5. 【数据挖掘基础算法】KNN最近邻分类算法

    算法简介: 通过计算待预测样本和已知分类号的训练样本之间的距离来判断该样本属于某个已知分类号的概率.并选取概率最大的分类号来作为待预测样本的分类号 懒惰分类算法,其模型的建立直到待预测实例进行预测时才 ...

  6. 我所遇到的C++连接问题汇总

    http://blog.sina.com.cn/s/blog_7caa399301017k1e.html 1:无法打开kernel32.lib 针对不同版本的VS,lib库所在的地方都不一样,所以首先 ...

  7. Linux 基础——权限管理命令chown、chgrp

    一.chown命令与chgrp命令的作用 有时你需要改变文件或目录的属主,比如有人离职或开发人员创建了一个在测试或生产环境中需要归属在系统账户下的应用.Linux提供了两个命令来实现这个功能:chow ...

  8. 【PAT】1001. A+B Format (20)

    1001. A+B Format (20) Calculate a + b and output the sum in standard format -- that is, the digits m ...

  9. day2 列表中常用的方法

    列表中有很多方法,下面来看看常用的方法,我们知道,字符串是以字符列表形式存储的.因此上面学习的字符串中的很多方法在列表中也有.     1.extend() extend()列表的扩展,把两个列表进行 ...

  10. js 正则验证多个邮箱,用;隔开的那种

    var r = /^((([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6}\;))*(([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\. ...