题目描述

如题,已知一个数列,你需要进行下面两种操作:

1.将某区间每一个数加上x

2.将某区间每一个数乘上x

3.求出某区间每一个数的和

输入输出格式

输入格式:

第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k

操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k

操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果


输出格式:

输出包含若干行整数,即为所有操作3的结果。

输入输出样例

输入样例#1:

5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
输出样例#1:

17
2

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=1000,M<=10000

对于100%的数据:N<=100000,M<=100000

(数据已经过加强^_^)

样例说明:

故输出应为17、2(40 mod 38=2)


需要越来越习惯lazy-tag的使用才行啊

tag1表示乘,tag2表示加

线段树的写法真是各有各的风格    大雾

 #include<cstdio>
#include<cstring>
#include<iostream>
using namespace std; typedef long long ll; inline int read(){
char ch;
int re=;
bool flag=;
while((ch=getchar())!='-'&&(ch<''||ch>''));
ch=='-'?flag=:re=ch-'';
while((ch=getchar())>=''&&ch<='') re=re*+ch-'';
return flag?-re:re;
} struct segment{
int l,r;
ll sum,tag1,tag2;
segment(){
sum=;
tag1=;
tag2=;
}
}; const int maxn=; int cnt,n,m;
ll mod;
segment tre[maxn<<];
int data[maxn]; inline void push_up(int x){
tre[x].sum=(tre[x<<].sum+tre[x<<|].sum)%mod;
} void build(int x,int l,int r){
tre[x].l=l; tre[x].r=r;
if(l==r){
tre[x].sum=data[l];
return;
}
int mid=(l+r)>>;
build(x<<,l,mid); build(x<<|,mid+,r);
push_up(x);
} void init(){
n=read(); m=read(); mod=read();
for(int i=;i<=n;i++) data[i]=read();
build(,,n);
} inline void push_down(int x){
int lson=x<<,rson=lson|; if(tre[x].tag1!=){
tre[lson].tag1=(tre[lson].tag1*tre[x].tag1)%mod;
tre[rson].tag1=(tre[rson].tag1*tre[x].tag1)%mod;
tre[lson].tag2=(tre[lson].tag2*tre[x].tag1)%mod;
tre[rson].tag2=(tre[rson].tag2*tre[x].tag1)%mod;
tre[lson].sum=(tre[lson].sum*tre[x].tag1)%mod;
tre[rson].sum=(tre[rson].sum*tre[x].tag1)%mod;
tre[x].tag1=;
} if(tre[x].tag2){
tre[lson].tag2=(tre[lson].tag2+tre[x].tag2)%mod;
tre[lson].sum=(tre[lson].sum+tre[x].tag2*(tre[lson].r-tre[lson].l+))%mod;
tre[rson].tag2=(tre[rson].tag2+tre[x].tag2)%mod;
tre[rson].sum=(tre[rson].sum+tre[x].tag2*(tre[rson].r-tre[rson].l+))%mod;
tre[x].tag2=;
}
} void update_add(int x,int L,int R,int c){
if(L<=tre[x].l&&tre[x].r<=R){
tre[x].tag2=(tre[x].tag2+c)%mod;
tre[x].sum=(tre[x].sum+c*(tre[x].r-tre[x].l+))%mod;
return;
} int mid=(tre[x].l+tre[x].r)>>;
if(tre[x].tag1!=||tre[x].tag2) push_down(x);
if(R<=mid) update_add(x<<,L,R,c);
else if(L>mid) update_add(x<<|,L,R,c);
else{ update_add(x<<,L,mid,c); update_add(x<<|,mid+,R,c); }
push_up(x);
} void update_mul(int x,int L,int R,int c){
if(L<=tre[x].l&&tre[x].r<=R){
tre[x].tag1=(tre[x].tag1*c)%mod;
tre[x].tag2=(tre[x].tag2*c)%mod;
tre[x].sum=(tre[x].sum*c)%mod;
return;
} int mid=(tre[x].l+tre[x].r)>>;
if(tre[x].tag1!=||tre[x].tag2) push_down(x);
if(R<=mid) update_mul(x<<,L,R,c);
else if(L>mid) update_mul(x<<|,L,R,c);
else{ update_mul(x<<,L,mid,c); update_mul(x<<|,mid+,R,c); }
push_up(x);
} ll query_sum(int x,int L,int R){
if(L<=tre[x].l&&tre[x].r<=R){
return tre[x].sum;
}
if(tre[x].tag1!=||tre[x].tag2) push_down(x);
int mid=(tre[x].l+tre[x].r)>>;
if(R<=mid) return query_sum(x<<,L,R);
if(L>mid) return query_sum(x<<|,L,R);
return (query_sum(x<<,L,mid)+query_sum(x<<|,mid+,R))%mod;
} void solve(){
int opt,L,R,c;
for(int i=;i<m;i++){
opt=read();
switch(opt){
case :{
L=read(); R=read(); c=read();
update_mul(,L,R,c);
break;
}
case :{
L=read(); R=read(); c=read();
update_add(,L,R,c);
break;
}
case :{
L=read(); R=read();
printf("%lld\n",query_sum(,L,R));
break;
}
}
}
} int main(){
//freopen("temp.in","r",stdin);
init();
solve();
return ;
}

她的话不多但笑起来是那么平静优雅

她柔弱的眼神里装的是什么 是思念的忧伤

luogu P3373 【模板】线段树 2的更多相关文章

  1. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  2. hdu 1754 I Hate It (模板线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others)    M ...

  3. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  4. 【线段树】【P3372】模板-线段树

    百度百科 Definition&Solution 线段树是一种log级别的树形结构,可以处理区间修改以及区间查询问题.期望情况下,复杂度为O(nlogn). 核心思想见百度百科,线段树即将每个 ...

  5. [Luogu] 可持久化线段树 1(主席树)

    https://www.luogu.org/problemnew/show/P3834 #include<cstdio> #include<iostream> #include ...

  6. 算法模板——线段树6(二维线段树:区域加法+区域求和)(求助phile)

    实现功能——对于一个N×M的方格,1:输入一个区域,将此区域全部值作加法:2:输入一个区域,求此区域全部值的和 其实和一维线段树同理,只是不知道为什么速度比想象的慢那么多,求解释...@acphile ...

  7. Luogu P5280 [ZJOI2019]线段树

    送我退役的神题,但不得不说是ZJOIDay1最可做的一题了 先说一下考场的ZZ想法以及出来后YY的优化版吧 首先发现每次操作其实就是统计出增加的节点个数(原来的不会消失) 所以我们只要统计出线段树上每 ...

  8. luogu 1712 区间(线段树+尺取法)

    题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭 ...

  9. Luogu P3960 列队 线段树

    题面 线段树入门题. 我们考虑线段树来维护这个矩阵. 首先我们先定n+1棵线段树前n棵维护每行前m-1个同学中没有离队过的同学,还有一棵维护第m列中没有离队过的同学.再定n+1棵线段树前n棵线段树维护 ...

  10. Luogu P1471 方差 线段树

    那是上上周...也是重构了四遍...后来GG了...今天又拾起,搞了搞终于过了... 好吧就是个线段树,公式懒得推了https://www.cnblogs.com/Jackpei/p/10693561 ...

随机推荐

  1. 安迪的第一个字典(Andy's First Dictionary,UVa 10815)

    Description Andy, , has a dream - he wants to produce his very own dictionary. This is not an easy t ...

  2. 微信JS-SDK开发 入门指南

    目录 前言 1. 过程 1.1 代码 1.2 代理 1.3 下载 1.4 解压 1.5 运行 1.6 查看 2. 微信接口测试 2.1 申请测试帐号 2.1.1 测试号信息 2.1.2 接口配置信息 ...

  3. ios移动端原生滚动条滚动不灵敏问题

    最近开发微信页面的时候遇到了这个问题, 因为移动端浏览器的原生滚动条样式很好,不像pc端那么难看,所以在页面需要滚动的地方用了原生的滚动条,这种滚动条在安卓浏览器中没有任何问题,但是在ios微信浏览器 ...

  4. Java(17)异常

    一.异常 1.1程序执行过程中出现的影响程序运行正常运行的现象.  1.2异常语法 try{ //代码块 }catch(异常类型 e){ }catch(异常类型 e){ }...{ }finally{ ...

  5. thinkphp5.0学习笔记(二)

    本文为公司制作API接口后台的小结! 1.命名注意事项: 不要使用易混淆的名字,如index,index01... 我喜欢用拼音... 比如: public function zhuce(Reques ...

  6. Python模块之ConfigParser - 读写配置文件

    Python 标准库的 ConfigParser 模块提供一套 API 来读取和操作配置文件. 配置文件的格式 a) 配置文件中包含一个或多个 section, 每个 section 有自己的 opt ...

  7. js中的数组对象排序(方法sort()详细介绍)

    定义和用法 sort() 方法用于对数组的元素进行排序. 语法    arrayObject.sort(sortby) 参数sortby:可选.规定排序顺序.必须是函数. 返回值 对数组的引用.请注意 ...

  8. Windows 10环境安装VIM代码补全插件YouCompleteMe

    Windows 10环境安装VIM代码补全插件YouCompleteMe 折腾一周也没搞定Windows下安装VIM代码补全插件YouCompleteMe,今天在家折腾一天总算搞定了.关键问题是在于P ...

  9. CentOS下安装php的mbstring扩展

    php的mbstring扩展如果没有安装会导致一些问题: 例1:登陆phpMyAdmin的时候会提示没字符串编码和字符串处理库 php_mbstring,有些程序中会用到mb_substr函数没有ph ...

  10. linux中怎么进入root用户

    如果你是第一次使用root用户,需要设置root用户密码:passwd root 根据提示输入然后切换到root用户:su root回车输入密码 回车