【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树
题目描述
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为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,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
样例输入
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
样例输出
2
35
题解
线段树裸题
唯一要注意的是两种标记的处理:pushdown中始终是先乘后加,而在乘的时候把原有的加标记也乘上这个数。原理应该不难想。
#include <cstdio>
#include <cstring>
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
typedef long long lint;
lint mod , sum[400010] , add[400010] , mul[400010];
void pushup(int x)
{
sum[x] = (sum[x << 1] + sum[x << 1 | 1]) % mod;
}
void pushdown(int l , int r , int x)
{
int mid = (l + r) >> 1;
if(mul[x] != 1)
{
sum[x << 1] = sum[x << 1] * mul[x] % mod;
sum[x << 1 | 1] = sum[x << 1 | 1] * mul[x] % mod;
add[x << 1] = add[x << 1] * mul[x] % mod;
add[x << 1 | 1] = add[x << 1 | 1] * mul[x] % mod;
mul[x << 1] = mul[x << 1] * mul[x] % mod;
mul[x << 1 | 1] = mul[x << 1 | 1] * mul[x] % mod;
mul[x] = 1;
}
if(add[x])
{
sum[x << 1] = (sum[x << 1] + add[x] * (mid - l + 1)) % mod;
sum[x << 1 | 1] = (sum[x << 1 | 1] + add[x] * (r - mid)) % mod;
add[x << 1] = (add[x << 1] + add[x]) % mod;
add[x << 1 | 1] = (add[x << 1 | 1] + add[x]) % mod;
add[x] = 0;
}
}
void build(int l , int r , int x)
{
mul[x] = 1;
if(l == r)
{
scanf("%lld" , &sum[x]);
sum[x] %= mod;
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
pushup(x);
}
void updatemul(int b , int e , lint m , int l , int r , int x)
{
if(b <= l && r <= e)
{
sum[x] = sum[x] * m % mod;
add[x] = add[x] * m % mod;
mul[x] = mul[x] * m % mod;
return;
}
pushdown(l , r , x);
int mid = (l + r) >> 1;
if(b <= mid) updatemul(b , e , m , lson);
if(e > mid) updatemul(b , e , m , rson);
pushup(x);
}
void updateadd(int b , int e , lint a , int l , int r , int x)
{
if(b <= l && r <= e)
{
sum[x] = (sum[x] + a * (r - l + 1)) % mod;
add[x] = (add[x] + a) % mod;
return;
}
pushdown(l , r , x);
int mid = (l + r) >> 1;
if(b <= mid) updateadd(b , e , a , lson);
if(e > mid) updateadd(b , e , a , rson);
pushup(x);
}
lint query(int b , int e , int l , int r , int x)
{
if(b <= l && r <= e)
return sum[x];
pushdown(l , r , x);
int mid = (l + r) >> 1;
lint ans = 0;
if(b <= mid) ans = (ans + query(b , e , lson)) % mod;
if(e > mid) ans = (ans + query(b , e , rson)) % mod;
return ans;
}
int main()
{
int n , m , p , l , r;
lint k;
scanf("%d%lld" , &n , &mod);
build(1 , n , 1);
scanf("%d" , &m);
while(m -- )
{
scanf("%d%d%d" , &p , &l , &r);
switch(p)
{
case 1: scanf("%lld" , &k); updatemul(l , r , k , 1 , n , 1); break;
case 2: scanf("%lld" , &k); updateadd(l , r , k , 1 , n , 1); break;
default: printf("%lld\n" , query(l , r , 1 , n , 1));
}
}
return 0;
}
【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树的更多相关文章
- 【BZOJ1798】【AHOI2009】维护序列(线段树)
题目链接 题解 这不就是luogu的线段树2的板子吗.... 没有任何的区别... 上代码吧... #include<iostream> #include<cstdio> #i ...
- BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 5504 Solved: 1937[Submit ...
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )
线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...
- 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(线段树区间操作)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 7773 Solved: 2792[Submit ...
- 1798: [Ahoi2009]Seq 维护序列seq
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 2930 Solved: 1087[Submit ...
- BZOJ_1798_[AHOI2009]维护序列_线段树
BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
随机推荐
- git忽略项gitegnore配置
在git中如果想忽略掉某个文件, 不让这个文件提交到版本库中,可以使用修改 .gitignore 文件的方法.这个文件每一行保存了一个匹配的规则 例如 # 此为注释 – 将被 Git 忽略 *.a # ...
- 北京Uber优步司机奖励政策(1月15日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 长沙Uber司机奖励政策(8月24日到8月30日)
本周奖励(8月24日到8月30日) 滴滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://w ...
- 【SQL】字符串去空格解决方法
一.表中字符串带空格的原因 1,空格就是空格. 2,控制符 显示为 空格. 二.解决方法 第一种情况,去空格的处理的比较简单,Replace(column,' ','') 就可以解决. 第二种情况,解 ...
- productFlavors 差异打包问题
差异化打包: 1.dependencies compile 是不可以放到差异化的productFlavors里面的. 会报错: Error:(69, 0) Could not find method ...
- Linux怎样创建FTP服务器--修改用户默认目录-完美解决 - 费元星
在创建FTP服务器之有先命令: ps -ef |grep vsftpd 查一下系统有没有安装vsftpd这个服务器,如果出现如下图所示的界面说明没有安装. 然后再执行:yum install vs ...
- 流式断言器AssertJ介绍
本文来自网易云社区 作者:范旭斐 大家在使用testng.junit做自动化测试的过程中,经常会用到testng.junit自带的断言器,有时候对一个字符串.日期.列表进行断言很麻烦,需要借助到jdk ...
- 卸载Oracle 11g
卸载oracle只需要执行deinstall.ba即可 运行.bat文件 按照提示步骤进行卸载 .bat文件所在目录需要手动删除,需要在程序管理器里面关掉Oracle的进程,在删除当前文件夹
- redhat防火墙管理
systemctl status firewalldsystemctl stop firewalldsystemctl start firewalldsystemctl enable firewall ...
- 新买的 SSD 固态硬盘竟然是坏的,我傻了啊!
1. 今天早上上班路上在网上下单了一个 1 T 的 SSD 固态硬盘,晚上 7 点半左右送到手后迫不及待想替换掉原来的机械硬盘,在这个新硬盘上装系统,玩起来. 2. 拆开包装,先用移动硬盘接口检查下新 ...