BZOJ1798[Ahoi2009]Seq 维护序列seq 题解
题目大意:
有长为N的数列,有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。
思路:
用线段树来维护当前的值和要加以及乘的值,由于加与乘是有序的,所以要在做子树之前将标记下传(注意顺序),加和乘分开来、合起来处理都可以。
代码:(当初手抽将1打成l一直RE调了半天才发现)
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAX 400000
#define LL long long
using namespace std; LL sum[MAX],mul[MAX],add[MAX],mod; void up_date(int cur)
{
sum[cur]=(sum[cur<<]+sum[cur<<|])%mod;
} void creat(int L,int R,int x,int y,int cur)
{
mul[cur]=;
add[cur]=;
sum[cur]+=y;
if (L==R) return;
int mid=L+R>>;
if (x>mid) creat(mid+,R,x,y,cur<<|);
else creat(L,mid,x,y,cur<<);
up_date(cur);
} void push_down(int cur,int l,int r,int mid)
{
if (mul[cur]== && add[cur]==) return;
mul[cur<<]=mul[cur<<]*mul[cur]%mod;
add[cur<<]=(add[cur<<]*mul[cur]%mod+add[cur])%mod;
sum[cur<<]=(sum[cur<<]*mul[cur]%mod+add[cur]*(LL)(mid-l+)%mod)%mod;
mul[cur<<|]=mul[cur<<|]*mul[cur]%mod;
add[cur<<|]=(add[cur<<|]*mul[cur]%mod+add[cur])%mod;
sum[cur<<|]=(sum[cur<<|]*mul[cur]%mod+add[cur]*(LL)(r-mid)%mod)%mod;
mul[cur]=;
add[cur]=;
return;
} void change_mul(int L,int R,int l,int r,int x,int cur)
{
if (L>=l && R<=r)
{
mul[cur]=mul[cur]*(LL)x%mod;
add[cur]=add[cur]*(LL)x%mod;
sum[cur]=sum[cur]*(LL)x%mod;
return;
}
int mid=L+R>>;
push_down(cur,L,R,mid);
if (l<=mid) change_mul(L,mid,l,r,x,cur<<);
if (r>mid) change_mul(mid+,R,l,r,x,cur<<|);
up_date(cur);
} void change_add(int L,int R,int l,int r,int x,int cur)
{
if (L>=l && R<=r)
{
add[cur]=(add[cur]+(LL)x)%mod;
sum[cur]=(sum[cur]+(LL)(R-L+)*x%mod)%mod;
return;
}
int mid=L+R>>;
push_down(cur,L,R,mid);
if (l<=mid) change_add(L,mid,l,r,x,cur<<);
if (r>mid) change_add(mid+,R,l,r,x,cur<<|);
up_date(cur);
} LL ask(int L,int R,int l,int r,int cur)
{
if (L>=l && R<=r) return sum[cur];
int mid=L+R>>;
LL ans=;
push_down(cur,L,R,mid);
if (l<=mid) ans=(ans+ask(L,mid,l,r,cur<<))%mod;
if (r>mid) ans=(ans+ask(mid+,R,l,r,cur<<|))%mod;
up_date(cur);
return ans;
} int main()
{
int n,m,a,b,c,i,x;
scanf("%d%lld",&n,&mod);
for (i=;i<=n;i++) scanf("%d",&a),creat(,n,i,a%mod,);
scanf("%d",&m);
for (i=;i<=m;i++)
{
scanf("%d",&x);
if (x==) scanf("%d%d%d",&a,&b,&c),change_mul(,n,a,b,c%mod,);
if (x==) scanf("%d%d%d",&a,&b,&c),change_add(,n,a,b,c%mod,);
if (x==) scanf("%d%d",&a,&b),printf("%lld\n",ask(,n,a,b,));
}
return ;
}
BZOJ1798[Ahoi2009]Seq 维护序列seq 题解的更多相关文章
- BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 5504 Solved: 1937[Submit ...
- 1798: [Ahoi2009]Seq 维护序列seq
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 2930 Solved: 1087[Submit ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )
线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 7773 Solved: 2792[Submit ...
- Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...
- 【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...
- [bzoj1798][Ahoi2009]Seq 维护序列seq ([洛谷P3373]【模板】线段树 2)
题目大意:有$n$个数,有$m$个操作,有三种: $1\;l\;r\;x:$把区间$[l,r]$内的数乘上$x$ $2\;l\;r\;x:$把区间$[l,r]$内的数加上$x$ $3\;l\;r:$询 ...
- BZOJ1798——[Ahoi2009]Seq维护序列seq
1.题目大意:区间修改乘法操作和加法操作,求区间和 2.分析:为了填补bzoj2631的坑还是写一发题解吧,首先呢,既然想要双标记,但是这两个标记之间又有着制约作用,所以要定义优先级,这个优先级就定义 ...
随机推荐
- selenium--python如何定位一组元素并返回文本值
from selenium import webdriverimport time a=[] #创建一个空列表用于存储查询到的元素组driver = webdriver.Firefox()driver ...
- 名词解释——Ext JS4
Ext.onReady——Ext主入口,和onload事件不同,不需要页面所有东西加在出来. Ext js 的基本语法就是使用树状图来配置对象来定义界面: { config_options1:valu ...
- 杂物 git rebase
- Oracle Segments可以跨多个data files吗?
首先,你需要明白的一点是:数据库的物理结构是由数据库的操作系统文件所决定,每一个Oracle数据库是由三种类型的文件组成:数据文件.日志文件和控制文件.数据库的文件为数据库信息提供真正的物理存储.每一 ...
- PHP数组合并的常见问题
一维数组的合并 <?php $arr1=array("a","b","c"); $arr2=array("c",& ...
- C和C++混合编程(__cplusplus 与 external "c" 的使用)
转自:http://blog.csdn.net/ljfth/article/details/3965871 第一种理解比如说你用C++开发了一个DLL库,为了能够让C语言也能够调用你的DLL输出(Ex ...
- 系统调用方式文件编程,王明学learn
系统调用方式文件编程 一.文件描述符 在Linux系统中,所有打开的文件也对应一个数字,这个数字由系统来分配,我们称之为:文件描述符. 二.函数学习 2.1打开文件 open 2.1.2 函数原形 ...
- [Unity3d插件]EasyTouch的初步使用
对于移动平台上的RPG类的游戏,我们常用虚拟摇杆来控制人物角色的行走和一些行为,相信我们对它并不陌生,之前尝试了EasyTouch2.5,发现并没有最新版的3.1好用,2.5版本的对于自适应没有做的很 ...
- 外键为','(逗号)拼接ID,连接查询外键表ID
select distinct pipeId=substring(a.PipeIn,b.number,charindex(',',a.PipeIn+',',b.number)-b.number) fr ...
- python web编程-web客户端编程
web应用也遵循客户服务器架构 浏览器就是一个基本的web客户端,她实现两个基本功能,一个是从web服务器下载文件,另一个是渲染文件 同浏览器具有类似功能以实现简单的web客户端的模块式urllib以 ...