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)
根据加减法原理,,
好像只能这么解释,
先放乘法标记
再放加法标记
注意查询的时候ll和rr是不变的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LLI long long
using namespace std;
const LLI MAXN=;
LLI read(LLI & n)
{
char p='+';LLI x=;
while(p<''||p>'')
p=getchar();
while(p>=''&&p<='')
x=x*+p-,p=getchar();
n=x;
}
LLI n,m,mod,wl,wr,wv,ans;
struct node
{
LLI l,r,w,fc,fj;
}a[MAXN];
void update(LLI k)
{
a[k].w=(a[k<<].w+a[k<<|].w)%mod;
}
void build_tree(LLI k,LLI ll,LLI rr)
{
a[k].l=ll;a[k].r=rr;
a[k].fc=;
a[k].fj=;
if(a[k].l==a[k].r)
{
read(a[k].w);
return ;
}
LLI mid=(ll+rr)/;
build_tree(k<<,ll,mid);
build_tree(k<<|,mid+,rr);
update(k);
}
void pushdown(LLI k,LLI ll,LLI rr,LLI mid)
{
a[k<<].w*=a[k].fc;a[k<<|].w*=a[k].fc;
a[k<<].w+=a[k].fj*(mid-ll+);a[k<<|].w+=a[k].fj*(rr-mid);
a[k<<].fc*=a[k].fc;a[k<<|].fc*=a[k].fc;
a[k<<].fj*=a[k].fc;a[k<<|].fj*=a[k].fc;
a[k<<].fj+=a[k].fj;a[k<<|].fj+=a[k].fj;
a[k].fc=;a[k].fj=;
a[k<<].w%=mod;a[k<<].fj%=mod;a[k<<].fc%=mod;
a[k<<|].w%=mod;a[k<<|].fj%=mod;a[k<<|].fc%=mod;
}
void interval_add(LLI k,LLI ll,LLI rr,LLI v)
{
if(a[k].l>rr||a[k].r<ll)
return ;
if(ll<=a[k].l&&rr>=a[k].r)
{
a[k].w=(a[k].w+v*(a[k].r-a[k].l+))%mod;
a[k].fj=(a[k].fj+v)%mod;
return ;
}
LLI mid=(a[k].l+a[k].r)/;
pushdown(k,a[k].l,a[k].r,mid);
//if(ll<=mid)
interval_add(k<<,ll,rr,v);
//if(rr>mid)
interval_add(k<<|,ll,rr,v);
update(k);
}
void interval_mul(LLI k,LLI ll,LLI rr,LLI v)
{
if(a[k].l>rr||a[k].r<ll)
return ;
if(ll<=a[k].l&&rr>=a[k].r)
{
a[k].w*=v%mod;
a[k].fc*=v%mod;
a[k].fj*=v%mod;
return ;
}
LLI mid=(a[k].l+a[k].r)/;
pushdown(k,a[k].l,a[k].r,mid);
//if(ll<=mid)
interval_mul(k<<,ll,rr,v);
//if(rr>mid)
interval_mul(k<<|,ll,rr,v);
update(k);
}
void interval_sum(LLI k,LLI ll,LLI rr)
{
if(a[k].l>rr||a[k].r<ll)
return ;
if(ll<=a[k].l&&rr>=a[k].r)
{
ans=(ans+a[k].w)%mod;
return ;
}
LLI mid=(a[k].l+a[k].r)/;
pushdown(k,a[k].l,a[k].r,mid);
//if(ll<=mid)
interval_sum(k<<,ll,rr);
//if(rr>mid)
interval_sum(k<<|,ll,rr);
}
int main()
{
read(n);read(m);read(mod);
build_tree(,,n);
for(LLI i=;i<=m;i++)
{
LLI p;
read(p);
if(p==)
{
read(wl);read(wr);read(wv);
interval_mul(,wl,wr,wv);
}
else if(p==)
{
read(wl);read(wr);read(wv);
interval_add(,wl,wr,wv);
}
else if(p==)
{
ans=;
read(wl);read(wr);
interval_sum(,wl,wr);
//cout<<ans%mod<<endl;
printf("%lld\n",ans%mod);
}
}
return ;
}
P3373 【模板】线段树 2 区间求和 区间乘 区间加的更多相关文章
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- hdu 1754 I Hate It (线段树功能:单点更新和区间最值)
版权声明:本文为博主原创文章.未经博主同意不得转载.vasttian https://blog.csdn.net/u012860063/article/details/32982923 转载请注明出处 ...
- 线段树&&线段树的创建线段树的查询&&单节点更新&&区间更新
目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...
- poj 1195:Mobile phones(二维线段树,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14391 Accepted: 6685 De ...
- 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 ...
- 线段树:Segment Tree(单点修改/区间修改模板) C++
线段树是非常有效的数据结构,可以快速的维护单点修改,区域修改,查询最大值,最小值等功能. 同时,它也很重要.如果有一天比赛,你卡在了一道线段树模板题目上,这就真的尴尬了.不过,随着时代的进步,题目也越 ...
- hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...
- Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模
D. The Child and Sequence At the children's day, the child came to Picks's house, and messed his h ...
- 线段树(成段更新,区间求和lazy操作 )
hdu1556 Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- 【线段树】HDU 3397 Sequence operation 区间合并
操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters i ...
随机推荐
- io计算
http://www.cnblogs.com/yalong_xiang/archive/2011/11/15/2249530.html ぬ儱←OWEN★ windows下如何查看磁盘IO性能 复制 ...
- CentOS 7加强安全性:
CentOS 7加强安全性:1. 更改 root 密码************************************************************************* ...
- web开发常见性能优化方式
经常使用的高并发. 高性能web,数据库server. 1.html 静态化 : 如新闻频道更新的非常快,都是通过cms静态生成(门户,信息公布类型的站点,交互性高的如猫扑的大杂烩也是静态化,实时静 ...
- 通讯编程入门--WEBSOCKET
C#通讯编程入门--WEBSOCKET WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System ...
- PAT Rational Arithmetic (20)
题目描写叙述 For two rational numbers, your task is to implement the basic arithmetics, that is, to calcul ...
- Spring和SpringMVC的关系
1.Spring和SpringMVC是父子容器关系. 2.Spring整体框架的核心思想是容器,用来管理bean的生命周期,而一个项目中会包含很多容器,并且它们分上下层关系,目前最常用的一个场景是在一 ...
- python爬虫【第1篇】
一.文件读写 1.打开文件 # 以读文件模式代开new.txt f=open(r"c:\new.txt",“r”) f=open("c:\new.txt",“r ...
- [计算机故障处理]EXCEL文件双击不能直接打开
同事的电脑里的EXCEL文件不知什么原因双击不能直接打开了,双击只能打开软件而且是没有任何表格的,但通过软件中的“打开”再找到指定的文件能打开. 解决方案: 打开excel,依次选择:工具-选项-常规 ...
- 64位win2008下IIS未开启32位支持导致DLL无法加载问题
部署一个WEB项目,在本机.本地服务器都没有问题,但部署到远程服务器以后,提示有个DLL无法加载: Server Error in '/' Application. Could not load fi ...
- 爬虫定时任务 redis 减轻 mysql 读的压力 加层
非工作时间,定时任务爬虫大量mysq短链接,影响了其他业务的,mysql 报 too many connections 错误 将爬虫url池放入到redis中,单独的脚本维护redis url池的更 ...