题目描述

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

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)

根据加减法原理,,

好像只能这么解释,

先放乘法标记

再放加法标记

注意查询的时候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 区间求和 区间乘 区间加的更多相关文章

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

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

  2. hdu 1754 I Hate It (线段树功能:单点更新和区间最值)

    版权声明:本文为博主原创文章.未经博主同意不得转载.vasttian https://blog.csdn.net/u012860063/article/details/32982923 转载请注明出处 ...

  3. 线段树&&线段树的创建线段树的查询&&单节点更新&&区间更新

    目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...

  4. poj 1195:Mobile phones(二维线段树,矩阵求和)

    Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14391   Accepted: 6685 De ...

  5. 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 ...

  6. 线段树:Segment Tree(单点修改/区间修改模板) C++

    线段树是非常有效的数据结构,可以快速的维护单点修改,区域修改,查询最大值,最小值等功能. 同时,它也很重要.如果有一天比赛,你卡在了一道线段树模板题目上,这就真的尴尬了.不过,随着时代的进步,题目也越 ...

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

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

  8. 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 ...

  9. 线段树(成段更新,区间求和lazy操作 )

    hdu1556 Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  10. 【线段树】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 ...

随机推荐

  1. Servlet的调试

    以下内容引用自http://wiki.jikexueyuan.com/project/servlet/debugging.html: 测试/调试Servlet始终是困难的.Servlets往往涉及大量 ...

  2. windows安装docker

    主要參考:http://docs.docker.com/installation/windows/ [1]安装完毕后同意后可能会报错: error in run: Failed to start ma ...

  3. Elasticsearch学习系列之配置文件详解

    ################################### Cluster ################################### #定义集群名称,默认是elasticse ...

  4. 配置文件的备份和IOS 的备份

    分享到 QQ空间 新浪微博 百度搜藏 人人网 腾讯微博 开心网 腾讯朋友 百度空间 豆瓣网 搜狐微博 百度新首页 QQ收藏 和讯微博 我的淘宝 百度贴吧 更多... 百度分享 广场 登录 注册 关注此 ...

  5. openTSDB ConnectionManager: Unexpected exception from downstream java.io.IOException: Broken pipe

    openTSDB有这种错误: ConnectionManager: Unexpected exception from downstream for [id: 0xf85323a8, /10.65.3 ...

  6. HDU1215--七夕节

    找出小于N的全部因子的和,N比較大,非常明显要打表来做,不然肯定会超时 方法就是枚举范围内每一个整数.然后再枚举范围内这个整数的全部的倍数,加上这个数 由于这个整数的倍数中一定含有这个整数因子,这样速 ...

  7. HDU1864_最大报销额(背包/01背包)

    解题报告 pid=1864">题目传送门 #include <cstdio> #include <cstring> #include <iostream& ...

  8. WCC框架设计

    一个好的框架,不仅能帮助程序开发节约很多时间,同时也能减少bug的引入.这个框架是在ssy同学的基础上进行了一些改进: 主要在于一下几点(会随着项目开发逐渐更新这篇文章) 1. 应用了反射机制,实现网 ...

  9. Matplotlib作图基础

    折线图 import matplotlib.pylab as pylab import numpy as npy x=[1,2,3,4,8] y=[5,7,2,1,5] #折线图 pylab.plot ...

  10. 抽象类(abstract class)和接口(interface)有什么异同?

    相同点: 1.抽象类和接口都不能被实例化,但可以定义抽象类和接口类型的引用. 2.一个类如果继承了抽象类和接口,必须要对其中的抽象方法全部实现.(接口中方法默认的是public abstract修饰的 ...