题目描述

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

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. vue-cli webpack在node环境下安装使用

    第一步,需要下载并安装node.js以及他的npm组件: 第二步,用node -v;npm -v来测试node.js以及npm是否安装成功(建议用GIT命令行工具,因为GIT是linux系统),如果显 ...

  2. 写了一个Mac快速设置、打开和关闭Web代理的Shell命令

    缘由(痛点) 每次在Mac上设置Web代理,都需要点开"系统偏好设置 -- 网络 -- 高级 -- 代理",然后分别设置Web代理(HTTP)和安全Web代理(HTTPS),设置完 ...

  3. java基础(二章)

    java基础(二章) 一,变量 1.变量是内存中的一个标识符号,用于存储数据 2.变量命名规则 l  必须以字母.下划线 _ .美元符号 $ 开头 l  变量中,可以包括数字 l  变量中,不能出现特 ...

  4. 关于redis内部的数据结构

    最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...

  5. 判断客户端使用的是安卓还是苹果,然后加载对应的css文件

    <script type="text/javascript" charset="utf-8"> var browser = { versions: ...

  6. Java基础——继承

    学习Java继承之前,我们想回忆一下Java面向对象需要特别注意的几个关键点. 面向对象是将复杂的事情简单化了,它通过封装的方式使得代码的重用性更高和安全性更强.平时我们要学会用面向对象的方式去思考, ...

  7. ionic2 tabs使用自定义图标

    在ionic2中图标是通过类添加的 比如说   tabIcon="homeImg" 在页面中研究可以看到在ios上有一个类是 .ion-ios-homeImg:before 所以我 ...

  8. 一个编程菜鸟的进阶之路(C/C++)

    学编程是一条不归路,但我义无反顾.只能往前冲,知道这个过程是痛苦的,所以我开通这个博客,记录自己在编程中遇到的问题和心得,一是希望可以帮助跟我一样遇到同样问题的人,二是把这作为对自己的勉励及回忆:

  9. nodejs+websocket制作聊天室视频教程

    本套教程主要讲解了node平台的安装,node初级知识.node 服务器端程序响应http请求,通过npm安装第三方包,websocket即时通讯.聊天页面界面制作.拖动原理.拖动效果.遮罩效果.定位 ...

  10. 理解容器之间的连通性 - 每天5分钟玩转 Docker 容器技术(34)

    通过前面小节的实践,当前 docker host 的网络拓扑结构如下图所示,今天我们将讨论这几个容器之间的连通性. 两个 busybox 容器都挂在 my_net2 上,应该能够互通,我们验证一下: ...