Description

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

Input

第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

Output

对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

Sample Input

7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

Sample Output

2
35
8

HINT

【样例说明】

初始时数列为(1,2,3,4,5,6,7)。
经过第1次操作后,数列为(1,10,15,20,25,6,7)。
对第2次操作,和为10+15+20=45,模43的结果是2。
经过第3次操作后,数列为(1,10,24,29,34,15,16}
对第4次操作,和为1+10+24=35,模43的结果是35。
对第5次操作,和为29+34+15+16=94,模43的结果是8。

测试数据规模如下表所示

数据编号 1 2 3 4 5 6 7 8 9 10
N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

线段树模板题

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
long long val;
long long mul;
long long add;
} Segt[+];
long long n,m,p,a[],INF; void build(long long node,long long a[],long long l,long long r)
{
Segt[node].add=;
Segt[node].mul=;//初始值要设正确
if (l==r)
Segt[node].val=a[l];
else
{
long long mid=(l+r)/;
build(node*,a,l,mid);
build(node*+,a,mid+,r);
Segt[node].val=(Segt[node*].val+Segt[node*+].val)%p;
}
} void Push(long long node,long long l,long long r)
{ if (Segt[node].mul!=)
{
//因为乘法可以影响区间的加法,但加法无法影响区间的乘法
//所以更新乘法的时候要把左右儿子的加法也乘上
Segt[node*].mul=(Segt[node*].mul*Segt[node].mul)%p;
Segt[node*+].mul=(Segt[node*+].mul*Segt[node].mul)%p;
Segt[node*].add=(Segt[node*].add*Segt[node].mul)%p;
Segt[node*+].add=(Segt[node*+].add*Segt[node].mul)%p; long long mid=(l+r)/;
Segt[node*].val=(Segt[node*].val*Segt[node].mul)%p;
Segt[node*+].val=(Segt[node*+].val*Segt[node].mul)%p;
Segt[node].mul=;
}
if (Segt[node].add!=)
{
Segt[node*].add=(Segt[node*].add+Segt[node].add)%p;
Segt[node*+].add=(Segt[node*+].add+Segt[node].add)%p;
long long mid=(l+r)/;
Segt[node*].val=(Segt[node*].val+Segt[node].add*(mid-l+))%p;
Segt[node*+].val=(Segt[node*+].val+Segt[node].add*(r-mid))%p;
Segt[node].add=;
}
} void MulUpdate(int node,int l,int r,int l1,int r1,int k)
{
if (r1<l || l1>r)
return;
if (l1<=l&&r<=r1)
{
Segt[node].val=(Segt[node].val*k)%p;
Segt[node].add=(Segt[node].add*k)%p;
Segt[node].mul=(Segt[node].mul*k)%p;
return;
}
Push(node,l,r);
long long mid=(l+r)/;
MulUpdate(node*,l,mid,l1,r1,k);
MulUpdate(node*+,mid+,r,l1,r1,k);
Segt[node].val=(Segt[node*].val+Segt[node*+].val)%p;
} void AddUpdate(long long node,long long l,long long r,long long l1,long long r1,long long k)
{
if (r1<l || l1>r)
return;
if (l1<=l&&r<=r1)
{
Segt[node].val=(Segt[node].val+k*(r-l+))%p;
Segt[node].add=(Segt[node].add+k)%p;
return;
}
Push(node,l,r);
long long mid=(l+r)/;
AddUpdate(node*,l,mid,l1,r1,k);
AddUpdate(node*+,mid+,r,l1,r1,k);
Segt[node].val=(Segt[node*].val+Segt[node*+].val)%p;
} long long Query(long long node,long long l,long long r,long long l1,long long r1)
{
if (l1>r||r1<l)
return ;
if (l1<=l&&r<=r1)
return Segt[node].val;
Push(node,l,r);
long long mid=(l+r)/;
return (Query(node*,l,mid,l1,r1)+Query(node*+,mid+,r,l1,r1))%p;
} int main()
{
long long x,y,k,h;
scanf("%lld%lld",&n,&p);
for (int i=; i<=n; ++i)
scanf("%lld",&a[i]);
scanf("%lld",&m);
build(,a,,n);
for (int i=; i<=m; ++i)
{
scanf("%lld",&h);
if (h==)
scanf("%lld%lld%lld",&x,&y,&k),MulUpdate(,,n,x,y,k);
if (h==)
scanf("%lld%lld%lld",&x,&y,&k),AddUpdate(,,n,x,y,k);
if (h==)
scanf("%lld%lld",&x,&y),printf("%lld\n",Query(,,n,x,y)%p);
}
}

1798. [AHOI2009]维护序列【线段树】的更多相关文章

  1. BZOJ1798[Ahoi2009]维护序列——线段树

    题目描述     老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成.    有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...

  2. [P2023][AHOI2009]维护序列(线段树)

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  3. [AHOI2009]维护序列 (线段树)

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  4. 洛谷 P2023 [AHOI2009]维护序列 || 线段树加法和乘法运算

    原理倒是非常简单.设原数为x,加法的lazytag为b,乘法的lazytag为a,操作数为c,那么原式为ax+b,乘上c后(ax+b)c=(ac)*x+b*c,加上c后(ax+b)+c=ax+(b+c ...

  5. [BZOJ1798][AHOI2009]Seq维护序列 线段树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 一眼看过去线段树,事实上就是线段树.对于乘和加的两个标记,我们可以规定一个顺序,比如 ...

  6. BZOJ 1798 AHOI2009 Seq 维护序列 线段树

    题目大意:维护一个序列,提供三种操作: 1.将区间中每个点的权值乘上一个数 2.将区间中每个点的权值加上一个数 3.求一段区间的和对p取模的值 2631的超^n级弱化版.写2631之前能够拿这个练练手 ...

  7. 【AHOI2009】 维护序列 - 线段树

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  8. 洛谷 P2023 BZOJ 1798 [AHOI2009]维护序列

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  9. 洛谷 P2023 维护序列——线段树

    先上一波题目 https://www.luogu.org/problem/P2023 复习了一波线段树 题目涉及的操作有区间加 区间乘以及区间求和 tips:线段树在传标记的时候 优先传乘法标记再传加 ...

随机推荐

  1. JSP学习笔记(1)-JSP简介

    1.什么是JSP? JSP是Java server page的缩写,有sun公司倡导,许多公司参与,于1999年推出的一种web服务设计标准.JSP基于Java Servlet以及整个java体系的W ...

  2. node.js(http协议)

    七层网络协议 应用层:浏览器(http,FTP,DNS,SMTP,TeInet)(邓哥)表示层:加密,格式转换(怕别人偷看,加密摩斯电码)会话层:解除或者建立和其他节点的联系(邓哥在想追这个女孩,不再 ...

  3. 在MyBatis中查询数据、涉及多参数的数据访问操作、插入数据时获取数据自增长的id、关联表查询操作、动态SQL、关于配置MyBatis映射没有代码提示的解决方案

    1. 单元测试 在单元测试中,每个测试方法都需要执行相同的前置代码和后置代码,则可以自定义2个方法,分别在这2个方法中执行前置代码和后置代码,并为这2个方法添加@Before和@After注解,然后, ...

  4. angular2上传图片

    话不多说,直接写 一.html页面 二.html代码:   <div class="descright"> <div class="clinic-img ...

  5. Ubuntu下编译opencv 和Ubuntu使用ffmpeg实现音频、视频的抽取

    一.使用Ubuntu编译opencv (前提是Ubuntu内已经正确配置了opencv,个人采用opencv3.2) g++ 1.cpp -o 1 `pkg-config --cflags --lib ...

  6. 如何配置Portal 基于AD的单点登录配置

    Portal for ArcGIS支持两种类型的账户,分别是: 1.系统内置账户. 2.外部系统的企业账户. 这两种不同的账号分别支持多种身份认证方式: 账号类型 认证方式 细分认证方式 系统内置账号 ...

  7. srop实战

    前言 srop 的作用比较强,在条件允许的情况下,尽量使用它.题目来自于 i春秋的一个比赛. 题目链接: https://gitee.com/hac425/blog_data/blob/master/ ...

  8. Base64编码和解码实现

    function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr ...

  9. 3 个简单、优秀的 Linux 网络监视器

    作者: Carla Schroder 译者: LCTT geekpi 用 iftop.Nethogs 和 vnstat 了解更多关于你的网络连接. 你可以通过这三个 Linux 网络命令,了解有关你网 ...

  10. Linux系统锁定关键文件

    锁定系统关键文件 1.密码.账号文件 chattr +i /etc/passwd /etc/group /etc/shadow /etc/gshadow /etc/inittab 加锁:chattr ...