题目描述

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

输入输出格式

输入格式:

第一行两个整数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)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

输出格式:

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

输入输出样例

输入样例#1: 复制

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

输出样例#1: 复制

2

35

8

说明

【样例说明】

初始时数列为(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

Source: Ahoi 2009

Solution

线段树的题目还真不能小看了...

这一道题花了我快一整节晚自习...

较之平常的线段树,会有一点不同.就是多了一个乘的操作.

所以我们需要令一个优先级,即先乘后加.

因为加无论什么时候加都没有关系,但是乘会对整个答案产生影响.

于是乎,只要打两个标记.在乘的时候,加的标记也要乘上那个值.

#include<bits/stdc++.h>
using namespace std;
const long long maxn=4000008;
long long n,m,p,num,pd;
long long x,y,k,ans;
long long w[maxn],add[maxn],mul[maxn];
long long build(long long x,long long L,long long R)
{
mul[x]=1;
if(L==R)
{
cin>>num;
return w[x]=num%p;
}
long long mid=(L+R)/2;
return w[x]=(build(x*2,L,mid)+build(x*2+1,mid+1,R))%p;
}
void down(long long x,long long l,long long r)
{
add[x*2]=(add[x]+add[x*2]*mul[x])%p;
add[x*2+1]=(add[x]+add[x*2+1]*mul[x])%p;
mul[x*2]=(mul[x*2]*mul[x])%p;
mul[x*2+1]=(mul[x*2+1]*mul[x])%p;
long long mid=(l+r)/2;
w[x*2]=(w[x*2]*mul[x]+add[x]*(mid-l+1))%p;
w[x*2+1]=(w[x*2+1]*mul[x]+add[x]*(r-mid))%p;
add[x]=0;
mul[x]=1;
}
long long query(long long x,long long L,long long R,long long l,long long r)
{
down(x,l,r);
if(l>=L&&r<=R)
return w[x]%p;
long long mid=(l+r)/2;
return ((L<=mid?query(x*2,L,R,l,mid):0)+(R>mid?query(x*2+1,L,R,mid+1,r):0))%p;
}
void update(long long x,long long v,long long pd,long long L,long long R,long long l,long long r)
{
down(x,l,r);
if(pd==1&&l>=L&&r<=R)
{
mul[x]=(mul[x]*v)%p;
add[x]=(add[x]*v)%p;
w[x]=(w[x]*mul[x])%p;
return;
}
if(pd==2&&l>=L&&r<=R)
{
add[x]=(add[x]+v)%p;
w[x]=(w[x]+add[x]*(r-l+1))%p;
return;
}
long long mid=(l+r)/2;
if(L<=mid)
update(x*2,v,pd,L,R,l,mid);
if(R>mid)
update(x*2+1,v,pd,L,R,mid+1,r);
w[x]=w[x*2]+w[x*2+1];
}
int main()
{
//ios::sync_with_stdio(false);
cin>>n>>p;
build(1,1,n);
cin>>m;
for(int i=1;i<=m;i++)
{
long long x,y,v;
cin>>pd;
if(pd!=3)
cin>>x>>y>>v,v%=p,
update(1,v,pd,x,y,1,n);
else
cin>>x>>y,
cout<<query(1,x,y,1,n)<<endl;
}
}

[AHOI2009]维护序列 (线段树)的更多相关文章

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

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

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

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

  3. 洛谷 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 ...

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

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

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

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

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

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

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

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

  8. COGS.1272.[AHOI2009]行星序列(线段树 区间加、乘、求和)

    题目链接 //注意取模! #include<cstdio> #include<cctype> using namespace std; const int N=1e5+5; i ...

  9. BZOJ_1798_[AHOI2009]维护序列_线段树

    BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...

随机推荐

  1. 分析(ExtractTransformLoad)与挖掘(DataMine)有何区别 ?

    首先,介绍一下ETL 和 DM:     ETL/Extraction-Transformation-Loading——用于完成DB到DW的数据转存,它将DB中的某一个时间点的状态,“抽取”出来,根据 ...

  2. ADO1

    1. 新建Web窗体 客户端控件:html控件 服务器控件:用的比较少 2. 数据库连接 protected void btnLogin_Click(object sender, EventArgs ...

  3. POJ 1739 Tony's Tour (插头DP,轮廓线DP)

    题意:给一个n*m的矩阵,其中#是障碍格子,其他则是必走的格子,问从左下角的格子走到右下角的格子有多少种方式. 思路: 注意有可能答案是0,就是障碍格子阻挡住了去路. 插头DP有两种比较常见的表示连通 ...

  4. codevs 1115 开心的金明

     时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房 ...

  5. HDU 4341 Gold miner (分组背包)

    先把线按照距离原点的距离排序,然后用叉积把在同一条直线上的点放在一起, 把在同一条线上的点中的前i个点当成一个点就转化成了分组背包. 写if(kas++) putchar('\n') 居然PE了,PE ...

  6. 数学题 追及相遇—HDOJ1275 人傻需要多做题

    两车追及或相遇问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  7. python_112_断言

    #断言 如果满足断言的执行程序,如果不满足则抛错误 assert type(1) is int print('断言正确的话,就继续执行') # assert type('a') is int #Ass ...

  8. ZOJ-1360 || POJ-1328——Radar Installation

    ZOJ地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=360 POJ地址:http://poj.org/problem?id ...

  9. Bootstrap 网页乱码

    问题:今天早上在实践bootstrap的时候,用EditPlus写代码,标签中包含了中文.在浏览器解析的时候中文部分生成的乱码.但是网页部分已经声明了使用utf-8的编码方式. 解决:网页字体正常显示 ...

  10. ios之NSURLRequest&NSURLConnection

    网络编程中一般都是经过  请求--->连接--->响应   (request  -->  connection  -->  response)这个过程. 一般的步骤是这样的: ...