题目描述

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

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. Windows 10+Ubuntu 16.04在MBR分区上安装双系统之后启动菜单的System Setup选项提示:can't find command "fwsetup"

    背景: 硬盘分区方式:MBR 硬盘容量256,Windows 100,Ubuntu 156,其中主分区安装的是Windows,Ubuntu安装在逻辑分区上,文件系统为Ext4,整个Ubuntu就挂载在 ...

  2. MongoDB小结20 - find【查询条件$size】

    size可以获得指定数组长度的文档 db.user.find({"fruit":{"$size":3}},{"_id":0}) { &quo ...

  3. oracle11g expdp/impdp数据库

    oracle11g导入/导出数据库 导出 .创建目录 sqlplus / as sysdba create directory dbDir as 'd:\oralce_sdic_backup\'; g ...

  4. MAVEN项目模块化

    maven的最大的特点之中的一个就是能够把项目模块化. 前面的一篇文章MAVEN创建并打包web项目已经创建了一个简单的webapp,注意这个webapp的打包方式是war. 假设如今又要划分出来一个 ...

  5. 一张图告诉你是须要 SQL 还是 Hadoop

    译序 非常多朋友问时下如火如荼的 Hadoop 是否适合引进我们自己的项目,什么时候用 SQL.什么时候用 Hadoop,它们之间怎样取舍?Aaron Cordova 用一张图来回答你这个问题,对于不 ...

  6. pat(A) 1063. Set Similarity(STL)

    代码: #include<cstdio> #include<cstring> #include<set> using namespace std; set<i ...

  7. [办公自动化]excel工作簿内的表无法删除,单击右键无删除键

    今天同事问,我自己的工作簿,没有设置保护,但是就是无法删除其中的工作表. 后来发现,她的excel工作簿打开的文件名后面显示[共享]. 原因找到了. 取消共享就可以了.

  8. 服务器端将复合json对象传回前端

    前端接收后端传过来的JSON对象,对前端来说,传过来的确实就是JSON对象:但后端,类型则灵活得多,可以是IList<>等类型,当然也可以是newtonsoft的JObject类型.反正在 ...

  9. springMVC之异常处理

    1. 自己定义一个异常类: UserException.java public class UserException extends RuntimeException { private stati ...

  10. [RK3288][Android6.0] 音频调试方法小结【转】

    本文转载自:http://blog.csdn.net/kris_fei/article/details/70053135 Platform: ROCKCHIPOS: Android 6.0Kernel ...