bzoj1798 维护序列
Description
Input
Output
Sample Input
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
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 维护序列的更多相关文章
- BZOJ1798 维护序列seq
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 8058 Solved: 2964[Submit ...
- 【双标记线段树】bzoj1798维护序列seq
一.题目 描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列 ...
- p2023&bzoj1798 维护序列
传送门(洛谷) 传送门(bzoj) 题目 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全 ...
- bzoj1798维护序列
题目链接 暴力数据结构之线段树$qwq$ 裸题直接敲板子 忘了啥时候写的了$qwq$ 直接上代码吧 /************************************************* ...
- BZOJ-1798 维护序列
线段树.支持区间加.区间乘.区间查询和. 标记下移还有取模要注意. var n,p,q,i,s,t:longint; a:int64; num,n1,n2,n3:array[0..500000] of ...
- BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 5504 Solved: 1937[Submit ...
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
- bzoj 维护序列seq(双标记线段树)
Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 4184 Solved: 1518[Submit][Status][Discus ...
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )
线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...
随机推荐
- hdu 3729 I'm Telling the Truth(二分匹配_ 匈牙利算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3729 I'm Telling the Truth Time Limit: 2000/1000 MS ( ...
- tf.segment_sum和tf.unsorted_segment_sum理解实例
本文来自 guotong1988 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/guotong1988/article/details/77622790 import ...
- idea关于断点的补充
黑背景版: 先编译好要调试的程序.1.设置断点
- 6.Python3标准库--数学运算
''' 作为一种通用的变成语言,Python经常用来解决数学问题.它包含一些用于管理整数和浮点数的内置类型,这很适合完成一般应用中可能出现的基本数学运算. 而标准库中包含一些用于满足更高级需求的模块. ...
- java版云笔记(二)
云笔记 基本的环境搭建好了,今天做些什么呢,第一是链接数据库(即搭建Spring-Batistas环境),第二是登录预注册. 注:这个项目的sql文件,需求文档,需要的html文件,jar包都可以去下 ...
- 百度2017春招<空间中最大三角形面积的问题>
题目: 三维空间中有N个点,每个点可能是三种颜色的其中之一,三种颜色分别是红绿蓝,分别用'R', 'G', 'B'表示. 现在要找出三个点,并组成一个三角形,使得这个三角形的面积最大.但是三角形必须满 ...
- 防范XSS跨站2
原文:http://blog.csdn.net/joeyon1985/article/details/43527987 在前面的一篇文章中,讲到了java web应用程序防止 csrf 攻击的方法,参 ...
- PostGreSQL数据库安装配置说明
windows 10 x64 pro 1703安装postgresql-9.6.3-2-windows-x64.exe数据库,步骤如下: 第一:下载数据库安装程序,下载地址为:https://www. ...
- 自组织神经网络介绍:自组织特征映射SOM(Self-organizing feature Map),第三部分
前面两篇介绍了SOM的基本概念和算法,第一部分,第二部分,本篇具体展开一下应用中的一些trick设定. SOM设计细节 输出层设计 输出层神经元数量设定和训练集样本的类别数相关,但是实际中我们往往不能 ...
- HTML常用标签及其属性
基本 <html>…</html> 定义 HTML 文档 <head>…</head> 文档的信息 <meta> HTML 文档的元信息 & ...