题目描述

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

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. mysql你确定掌握的那些sql语句

    1.创建表 create table test(uid int not null,create_time timestamp default current_timestamp); 即:没有双引号,单 ...

  2. LoadRunner脚本编写

    性能測试project师要懂代码么?答案是必须的.好多測试员觉得在loadrunner中编写脚本非常难非常牛X ,主要是大多測试人员并未做过开发工作,大学的那点程序基础也忘记的几乎相同了. 还有非计算 ...

  3. web开发常见性能优化方式

    经常使用的高并发. 高性能web,数据库server.  1.html 静态化 : 如新闻频道更新的非常快,都是通过cms静态生成(门户,信息公布类型的站点,交互性高的如猫扑的大杂烩也是静态化,实时静 ...

  4. [TypeScript] Overload a Function with TypeScript’s Overload Signatures

    Some functions may have different return types depending on the types of the arguments with which th ...

  5. 使用Docker部署Gitlab

    由于公司的代码server已使用Gitosis搭建,但由于用户和权限管理太麻烦. 如今想在原有server上再搭建Gitlab,使用Gitlab官方方法直接安装. 会导致与Gitosis冲突,使得Gi ...

  6. c#实例化继承类,必须对被继承类的程序集做引用 .net core Redis分布式缓存客户端实现逻辑分析及示例demo 数据库笔记之索引和事务 centos 7下安装python 3.6笔记 你大波哥~ C#开源框架(转载) JSON C# Class Generator ---由json字符串生成C#实体类的工具

    c#实例化继承类,必须对被继承类的程序集做引用   0x00 问题 类型“Model.NewModel”在未被引用的程序集中定义.必须添加对程序集“Model, Version=1.0.0.0, Cu ...

  7. HDU 4352 XHXJ&#39;s LIS(数位dp&amp;状态压缩)

    题目链接:[kuangbin带你飞]专题十五 数位DP B - XHXJ's LIS 题意 给定区间.求出有多少个数满足最长上升子序列(将数看作字符串)的长度为k. 思路 一个数的上升子序列最大长度为 ...

  8. storm与hadoop的对照

       hadoop 是实现了 mapreduce 的思想,将数据切片计算来处理大量的离线数据. hadoop处理的数据必须是已经存放在 hdfs 上或者类似 hbase 的数据库中.所以 hadoop ...

  9. python包格式

    1 egg和wheel 前者扩展名是.egg,后者扩展名是.whl 它们都是python的模块.后者用来替换前者. wheel是轮子的意思,就是说,有了.whl包就不需要重新再造轮子了.

  10. ios33--线程通信

    // // ViewController.m // 06-掌握-线程间通信 // // atomic:为set方法加锁,线程安全,需要消耗资源. // nonatomic:不为set方法加锁,非线程安 ...