Luogu 3373 又乘又加的线段树

当给一个节点加上一个加法标记时,直接把加法标记 += 新值;

当给一个节点加上一个乘法标记时,把乘法标记和加法标记同时 *= 新值。(注意pushdown函数中也要这样!)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define space putchar(' ')
#define enter putchar('\n')
template <class T>
bool read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
else if(c == EOF) return 0;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
return 1;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}
const int N = 100005;
int n, m, P;
ll a[N], data[4*N], mul[4*N], add[4*N];
void calc(ll &x, ll y, ll z){ // x = x * y + z
x = (x * y % P + z % P) % P;
}
void build(int k, int l, int r){
mul[k] = 1;
if(l == r) return (void)(data[k] = a[l]);
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
data[k] = (data[k << 1] + data[k << 1 | 1]) % P;
}
void pushdown(int k, int l, int r){
if(mul[k] == 1 && add[k] == 0) return;
int mid = (l + r) >> 1;
calc(data[k << 1], mul[k], add[k] * (mid - l + 1));
calc(data[k << 1 | 1], mul[k], add[k] * (r - mid));
calc(mul[k << 1], mul[k], 0);
calc(mul[k << 1 | 1], mul[k], 0);
calc(add[k << 1], mul[k], add[k]);
calc(add[k << 1 | 1], mul[k], add[k]);
mul[k] = 1, add[k] = 0;
}
void change(int k, int l, int r, int ql, int qr, ll x, bool is_mul){
if(ql <= l && qr >= r){
if(is_mul){
data[k] = data[k] * x % P;
mul[k] = mul[k] * x % P;
add[k] = add[k] * x % P;
}
else{
data[k] = (data[k] + x * (r - l + 1) % P) % P;
add[k] = (add[k] + x) % P;
}
return;
}
pushdown(k, l, r);
int mid = (l + r) >> 1;
if(ql <= mid) change(k << 1, l, mid, ql, qr, x, is_mul);
if(qr > mid) change(k << 1 | 1, mid + 1, r, ql, qr, x, is_mul);
data[k] = (data[k << 1] + data[k << 1 | 1]) % P;
}
ll query(int k, int l, int r, int ql, int qr){
if(ql <= l && qr >= r) return data[k];
pushdown(k, l, r);
int mid = (l + r) >> 1;
ll ret = 0;
if(ql <= mid) ret = (ret + query(k << 1, l, mid, ql, qr)) % P;
if(qr > mid) ret = (ret + query(k << 1 | 1, mid + 1, r, ql, qr)) % P;
return ret;
}
int main(){
read(n), read(m), read(P);
for(int i = 1; i <= n; i++)
read(a[i]), a[i] %= P;
build(1, 1, n);
while(m--){
int op, l, r;
read(op), read(l), read(r);
if(op < 3){
ll x;
read(x);
if(op == 2) change(1, 1, n, l, r, x, 0);
else change(1, 1, n, l, r, x, 1);
}
else write(query(1, 1, n, l, r)), enter;
}
return 0;
}

Luogu 3373 又乘又加的线段树的更多相关文章

  1. Luogu 45887 全村最好的嘤嘤刀(线段树 树状数组)

    https://www.luogu.org/problemnew/show/T45887 题目背景 重阳节到了,我们最好的八重樱拥有全村最好的嘤嘤刀…… 题目描述 在绯玉丸力量的影响下,八重村成了一条 ...

  2. luogu P5142 区间方差 十分优美的线段树

    又来了个维护方差的线段树.... 大致推导过程(字丑多包涵QAQ) 注意取模时要加一些100000007防止出现负数.. #include<cstdio> #include<iost ...

  3. luogu P3834 【模板】可持久化线段树 1(主席树) 查询区间 [l, r] 内的第 k 小/大值

    ————————————————版权声明:本文为CSDN博主「ModestCoder_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https:// ...

  4. luogu P1712 [NOI2016]区间 贪心 尺取法 线段树 二分

    LINK:区间 没想到尺取法. 先说暴力 可以发现答案一定可以转换到端点处 所以在每个端点从小到大扫描线段就能得到答案 复杂度\(n\cdot m\) 再说我的做法 想到了二分 可以进行二分答案 从左 ...

  5. luogu P4632 [APIO2018] New Home 新家 线段树 set 二分

    写了一种比较容易理解 但是常数很大的sol. 容易发现可以扫描线. 维护好序列之后发现很难查距离 考虑二分. 这里二分可以在线段树上进行 当然可能存在一些问题 如果离散化的话需要处理一些比较麻烦的细节 ...

  6. 【LUOGU???】WD与地图 整体二分 线段树合并

    题目大意 有一个简单有向图.每个点有点权. 有三种操作: 修改点权 删除一条边 询问和某个点在同一个强连通分量中的点的前 \(k\) 大点权和. \(n\leq 100000,m,q\leq 2000 ...

  7. bzoj 3196 && luogu 3380 JoyOI 1730 二逼平衡树 (线段树套Treap)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3196 题面; 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Se ...

  8. Luogu 4556 雨天的尾巴 - 启发式合并线段树

    Solution 用$col$记录 数量最多的种类, $sum$记录 种类$col$ 的数量. 然后问题就是树上链修改, 求 每个节点 数量最多的种类. 用树上差分 + 线段树合并更新即可. Code ...

  9. hdu 5111 树链剖分加函数式线段树

    这题说的是给了两棵树,各有100000 个节点,然后Q个操作Q<=50000; 每个操作L1 R1 L2 R2.因为对于每棵树都有一个与本棵树其他点与众不同的值, 最后问 在树上从L1到R1这条 ...

随机推荐

  1. 浅谈ajax同步、异步的问题

    最近实习的时候看到过firefox的同步.异步的警告,想着概念不是那么清楚,于是整理了一下ajax同步异步方面的知识.我是小白,做个笔记. 首先就是概念问题,ajax根据async进行区分同步和异步过 ...

  2. Spring Boot之拦截器与过滤器(完整版)

    作者:liuxiaopeng 链接:http://www.cnblogs.com/paddix 作者:蓝精灵lx原文:https://blog.csdn.net/liuxiao723846/artic ...

  3. hostname命令详解

    基础命令学习目录首页 原文链接:https://idc.wanyunshuju.com/cym/68.html Linux操作系统的hostname是一个kernel变量,可以通过hostname命令 ...

  4. Django_rest_framework_版本(待验证)

    简介 API版本控制可以用来在不同的客户端使用不同的行为.REST框架提供了大量不同的版本设计. 版本控制是由传入的客户端请求决定的,并且可能基于请求URL,或者基于请求头. 有许多有效的方法达到版本 ...

  5. DB2分页查询简单示例

    select * from ( select a.* ,rownumber() over(order by create_time desc) as rowid from ( select * fro ...

  6. mysql/mybatis之合并两个表的查询结果

    下面这段sql是把两个表中各自符合条件的count值相加,返回结果是两个之和 SELECT sum(result) FROM ( SELECT COUNT(*) result FROM TEST_A ...

  7. json转对象

    1,引入依赖 <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib& ...

  8. 《Spring1之第七次站立会议》

    <第七次站立会议> 昨天:我把自己项目工程里的服务器端界面进行了优化和完善. 今天:我查找了关于实现视频功能的相关代码. 遇到的问题:找到的都是基于C#的相关代码,很难找到用java实现的 ...

  9. 用原生JS实现多张图片上传及预览功能(兼容IE8)

    最近需要做一个图片上传预览的功能(兼容IE8-11.chrome.firefox等浏览器),网上现有的文件上传组件(如webuploader)总是会遇到一些兼容性问题.于是我参考了一些博文(链接找不到 ...

  10. 《软件工程和Python》第0周作业1

    写在前面的话 欢迎大家开始一段新的课程学习!从开博客开始吧.每次博客作业都会有评分,计入总成绩哦. 1.   截止日期 本次作业的提交截止时间:见老师要求 2.   作业要求 (1)建立个人技术博客和 ...