【原创】洛谷 LUOGU P3373 【模板】线段树2
P3373 【模板】线段树 2
题目描述
如题,已知一个数列,你需要进行下面两种操作:
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的结果。
输入输出样例
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
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)
// LUOGU 3373 【模板】线段树2
// 2017.7.20 20:52
#include<bits/stdc++.h>
#define INF 0x3fffffff
#define MAXN 100000
#define MAXT MAXN*4
using namespace std;
typedef long long ll;
int N,M,topt=;
ll P,a[MAXN+];
struct sgt_node{
int lc,rc;
ll sum,pls,mul;
sgt_node(){pls=,mul=INF;}
}sgt[MAXT+];
int getint(){
char ch='*';
while(!isdigit(ch=getchar()));
int num=ch-'';
while(isdigit(ch=getchar()))num=num*+ch-'';
return num;
}
ll getll(){
char ch='*';
while(!isdigit(ch=getchar()));
ll num=ch-'';
while(isdigit(ch=getchar()))num=num*+ch-'';
return num;
}
#define lch sgt[now].lc
#define rch sgt[now].rc
#define smid ((l+r)>>1)
void update(int now){
sgt[now].sum=(sgt[lch].sum+sgt[rch].sum)%P;
}
void set_mul(int now,ll v){
sgt[now].sum=(sgt[now].sum*v)%P;
if(sgt[now].mul==INF)sgt[now].mul=v%P;
else sgt[now].mul=(sgt[now].mul*v)%P; // 必须为乘法!!!
sgt[now].pls=(sgt[now].pls*v)%P;
}
void set_pls(int now,int l,int r,ll v){
sgt[now].sum=(sgt[now].sum+v*(r-l+))%P;
sgt[now].pls=(sgt[now].pls+v)%P;
}
void push_down(int now,int l,int r){
if(sgt[now].mul!=INF){
set_mul(lch,sgt[now].mul);
set_mul(rch,sgt[now].mul);
sgt[now].mul=INF;
}
if(sgt[now].pls){
set_pls(lch,l,smid,sgt[now].pls);
set_pls(rch,smid+,r,sgt[now].pls);
sgt[now].pls=;
}
}
void Build_sgt(int &now,int l,int r){
now=++topt;
if(l==r){
sgt[now].sum=a[l];
return;
}
Build_sgt(lch,l,smid);
Build_sgt(rch,smid+,r);
update(now);
}
ll Query_sgt(int now,int l,int r,int qx,int qy){
if(l==qx&&r==qy)return sgt[now].sum;
push_down(now,l,r);
if(qy<=smid)return Query_sgt(lch,l,smid,qx,qy);
if(qx>smid)return Query_sgt(rch,smid+,r,qx,qy);
return Query_sgt(lch,l,smid,qx,smid)+Query_sgt(rch,smid+,r,smid+,qy);
}
void Region_mul(int now,int l,int r,int x,int y,ll v){
if(l==x&&r==y){
set_mul(now,v);
return;
}
push_down(now,l,r);
if(y<=smid)Region_mul(lch,l,smid,x,y,v);
else if(x>smid)Region_mul(rch,smid+,r,x,y,v);
else{
Region_mul(lch,l,smid,x,smid,v);
Region_mul(rch,smid+,r,smid+,y,v);
}
update(now);
}
void Region_pls(int now,int l,int r,int x,int y,ll v){
if(l==x&&r==y){
set_pls(now,l,r,v);
return;
}
push_down(now,l,r);
if(y<=smid)Region_pls(lch,l,smid,x,y,v);
else if(x>smid)Region_pls(rch,smid+,r,x,y,v);
else{
Region_pls(lch,l,smid,x,smid,v);
Region_pls(rch,smid+,r,smid+,y,v);
}
update(now);
}
int main(){
N=getint(),M=getint(),P=getll();
for(int i=;i<=N;i++)
a[i]=getll();
int root=;
Build_sgt(root,,N);
int op,x,y;
ll k;
for(int i=;i<=M;i++){
op=getint();
switch(op){
case :
x=getint(),y=getint(),k=getll();
Region_mul(,,N,x,y,k);
break;
case :
x=getint(),y=getint(),k=getll();
Region_pls(,,N,x,y,k);
break;
case :
x=getint(),y=getint();
printf("%lld\n",Query_sgt(,,N,x,y)%P);
break;
}
}
return ;
}
【原创】洛谷 LUOGU P3373 【模板】线段树2的更多相关文章
- 【洛谷 p3372】模板-线段树 1(数据结构--线段树)
题目:已知一个数列,你需要进行下面两种操作:1.将某区间每一个数加上x:2.求出某区间每一个数的和. 解法:如题,模版题.需要加上 lazy 标记,也就是我的 upd.lazy 标记的思路就是对一个结 ...
- 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
- 洛谷p3384【模板】树链剖分题解
洛谷p3384 [模板]树链剖分错误记录 首先感谢\(lfd\)在课上调了出来\(Orz\) \(1\).以后少写全局变量 \(2\).线段树递归的时候最好把左右区间一起传 \(3\).写\(dfs\ ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 洛谷P3834 可持久化线段树(主席树)模板
题目:https://www.luogu.org/problemnew/show/P3834 无法忍受了,我要写主席树! 解决区间第 k 大查询问题,可以用主席树,像前缀和一样建立 n 棵前缀区间的权 ...
- 洛谷 P3384 【模板】树链剖分
树链剖分 将一棵树的每个节点到它所有子节点中子树和(所包含的点的个数)最大的那个子节点的这条边标记为"重边". 将其他的边标记为"轻边". 若果一个非根节点的子 ...
- 洛谷题解P4314CPU监控--线段树
题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...
- 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)
Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...
- 『题解』洛谷P3384 【模板】树链剖分
Problem Portal Portal1: Luogu Description 如题,已知一棵包含\(N\)个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作\(1\): ...
随机推荐
- 【Python基础】04_Python中的if判断语句
1.if基本语法 if 要判断的条件: 条件成立时,要做的事情 ...... 注:代码缩进为一个 tab 键,或者4个空格 ——建议使用空格 if语句和缩进部分是一个完整的代码块 2. ...
- Creating mailbox file: 文件已存在
原来linux下添加用户后,会在系统里自动加一个邮箱(系统邮箱),路径是:/var/spool/mail/用户名.可以直接用命令#rm -rf /var/spool/mail/用户名 这样就可以再次添 ...
- AOP与IOC区别
Spring核心知识 Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Devel ...
- python+django学习三
在这个网站看https://sshwsfc.github.io/xadmin/ xadmin结果一堆的坑,文档找不到界面,dome登陆就报错permission denied for rela ...
- .Net Core项目如何设置静态页面为项目的启动页面?
最近在使用Core的webApi作为服务器端的数据提供者,但是需要有自己的官网,来指导前端如何使用该接口,因为不想接入MVC这么大的框架,于是写了个静态页面挂上doc文档提供下载就行. 在项目的Sta ...
- LeetCode 腾讯精选50题--子集
根据题意,找到几何中的所有子集,说实话子集是没有什么头绪的,因为如果采用遍历的方法,稍有遗漏不说,代码的嵌套循环层数随着数组大小的增加而增加,想了很久没有头绪后就去看了看评论,然后就被点破了解题的关键 ...
- echarts 内存泄漏
最近使用vue + Echarts 实现vue项目的数据可视化功能的时候,在ios环境下,点击列表页进入详情页几次就白屏了. 感觉白屏的原因是:echarts频繁初始化画图时候有内存泄漏,吃掉了所有内 ...
- canvas-八卦图和时钟实现
八卦图: <body> canvas id="></canvas> <script> //获取到画布元素 let myCanvas = docume ...
- debian上安装tmux
1.安装ncurses库 1.1.获取源码 wget https://invisible-island.net/datafiles/release/ncurses.tar.gz tar xvf ncu ...
- 【Distributed】分布式Session一致性问题
一.概述 1.1 什么是Session 1.2 Session实现原理 1.3 Session常见问题 Session 保证在那里? 关闭浏览器Session会失效吗 服务器集群之后,Session产 ...