传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1798

注意,应保证当前节点维护的值是正确的,lazy tag只是一个下传标记,在下传时应即时更新儿子的维护值,在修改时也应即时更新当前节点的维护值。

#include <cstdio>

const int maxn = 100005;

int n, mod, a[maxn], m, t1, t2, t3, opr;
struct Node {
int ql, qr;
long long sm, mul, add;
} tree[maxn << 2]; inline void pushup(int p) {
tree[p].sm = (tree[p << 1].sm + tree[p << 1 | 1].sm) % mod;
}
inline void pushdown(int p) {
tree[p << 1].mul = tree[p << 1].mul * tree[p].mul % mod;
tree[p << 1].add = (tree[p << 1].add * tree[p].mul + tree[p].add) % mod;
tree[p << 1].sm = (tree[p << 1].sm * tree[p].mul + tree[p].add * (tree[p << 1].qr - tree[p << 1].ql + 1)) % mod; tree[p << 1 | 1].mul = tree[p << 1 | 1].mul * tree[p].mul % mod;
tree[p << 1 | 1].add = (tree[p << 1 | 1].add * tree[p].mul + tree[p].add) % mod;
tree[p << 1 | 1].sm = (tree[p << 1 | 1].sm * tree[p].mul + tree[p].add * (tree[p << 1 | 1].qr - tree[p << 1 | 1].ql + 1)) % mod; tree[p].mul = 1;
tree[p].add = 0;
}
void make_tree(int p, int left, int right) {
tree[p].ql = left;
tree[p].qr = right;
tree[p].mul = 1;
if (left == right) {
tree[p].sm = (long long)(a[left] % mod);
return;
}
int mid = (left + right) >> 1;
make_tree(p << 1, left, mid);
make_tree(p << 1 | 1, mid + 1, right);
pushup(p);
}
void mull(int p, int left, int right, int c) {
if (tree[p].ql == left && tree[p].qr == right) {
tree[p].mul = tree[p].mul * (long long)c % mod;
tree[p].add = tree[p].add * (long long)c % mod;
tree[p].sm = tree[p].sm * (long long)c % mod;
return;
}
pushdown(p);
int mid = (tree[p].ql + tree[p].qr) >> 1;
if (right <= mid) {
mull(p << 1, left, right, c);
}
else if (left > mid) {
mull(p << 1 | 1, left, right, c);
}
else {
mull(p << 1, left, mid, c);
mull(p << 1 | 1, mid + 1, right, c);
}
pushup(p);
}
void addd(int p, int left, int right, int c) {
if (tree[p].ql == left && tree[p].qr == right) {
tree[p].add = (tree[p].add + (long long)c) % mod;
tree[p].sm = (tree[p].sm + (long long)c * (long long)(tree[p].qr - tree[p].ql + 1)) % mod;
return;
}
pushdown(p);
int mid = (tree[p].ql + tree[p].qr) >> 1;
if (right <= mid) {
addd(p << 1, left, right, c);
}
else if (left > mid) {
addd(p << 1 | 1, left, right, c);
}
else {
addd(p << 1, left, mid, c);
addd(p << 1 | 1, mid + 1, right, c);
}
pushup(p);
}
int qry(int p, int left, int right) {
if (tree[p].ql == left && tree[p].qr == right) {
return (int)tree[p].sm;
}
pushdown(p);
int mid = (tree[p].ql + tree[p].qr) >> 1, rt;
if (right <= mid) {
rt = qry(p << 1, left, right);
}
else if (left > mid) {
rt = qry(p << 1 | 1, left, right);
}
else {
rt = qry(p << 1, left, mid);
rt = (rt + qry(p << 1 | 1, mid + 1, right)) % mod;
}
pushup(p);
return rt;
} int main(void) {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d%d", &n, &mod);
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i);
}
make_tree(1, 1, n);
scanf("%d", &m);
while (m--) {
scanf("%d%d%d", &opr, &t1, &t2);
if (opr == 1) {
scanf("%d", &t3);
mull(1, t1, t2, t3);
}
else if (opr == 2) {
scanf("%d", &t3);
addd(1, t1, t2, t3);
}
else {
printf("%d\n", qry(1, t1, t2));
}
}
return 0;
}

  

_bzoj1798 [Ahoi2009]Seq 维护序列seq【线段树 lazy tag】的更多相关文章

  1. 【BZOJ1798】【AHOI2009】维护序列(线段树)

    题目链接 题解 这不就是luogu的线段树2的板子吗.... 没有任何的区别... 上代码吧... #include<iostream> #include<cstdio> #i ...

  2. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

  3. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  4. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  5. BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5504  Solved: 1937[Submit ...

  6. bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7773  Solved: 2792[Submit ...

  7. 1798: [Ahoi2009]Seq 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 2930  Solved: 1087[Submit ...

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

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

  9. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

随机推荐

  1. chrome插件vimium的安装和使用

    vimium工具的作用:使你脱离鼠标,使用键盘方便操作页面,默认对所有网站生效 1.chrome商店里有的,但是,我怎么安装,都不行 2.源码安装:http://vimium.github.io/ h ...

  2. hibernate4中HHH000273的错误

    今天配置hibernate4.发现报 17:55:06,815 INFO AbstractPoolBackedDataSource:522 - Initializing c3p0 pool... co ...

  3. react-redux 之 provider 和 connect

    1.Provider 提供的是一个顶层容器的作用,实现store的上下文传递 2.connect 可以把state和dispatch绑定到react组件,使得组件可以访问到redux的数据 react ...

  4. FFMpeg2.4.2 on Ubuntu14.04

     FFmpeg 2.4 "Fresnel" – is the leading multimedia framework, cross-platform solution tha ...

  5. 跟面试官讲Binder(零)

    面试的时候,面试官问你说,简单说一下Android的Binder机制,你会怎么回答? 我想,我会这么说. 在Android启动的时候,Zygote进程孵化出第一个子进程叫SystemServer,而在 ...

  6. 机器学习和深度学习笔记(Matlab语言实现)

    不多说,直接上干货! 这里,对于想用matlab语言来做的朋友,强烈推荐 http://www.cnblogs.com/tornadomeet/

  7. 嵌入式开发之davinci--- 8148 小站信息

    http://zhan.renren.com/tag?value=dm8148#!//more/3602888498051423017 http://zhan.renren.com/dm8148evm ...

  8. UISlider无法拖动进度条的问题解决

    UISlider无法拖动进度条的问题解决 最近业务中的视频播放使用到了UISlider,但是有一个奇怪的问题,就是在Modar出来的控制器中UISlider是可以正常使用的,但是在Push出来的控制器 ...

  9. XML简单介绍及举例

    可扩展标记语言(eXtensibleMarkup Language,简称XML).是一种标记语言.标记指计算机所能理解的信息符号.通过此种标记,计算机之间能够处理包括各种信息的文章等. 怎样定义这些标 ...

  10. 蓝牙4.0 BLE 广播包解析

    在使用EN-Dongle捕获和解析广播包之前,我们先了解一下BLE报文的结构,之后,再对捕获的广播包进行分析.在学习BLE的时候,下面两个文档是极其重要的,这是SIG发布的蓝牙的核心协议和核心协议增补 ...