题意:

操作有:区间加,区间乘,区间询问求和

思路:

设一个数为\(m*sum+a\),加就变成了\(m*sum+a+a_2\),乘就变成了\(m*m_2*sum+a*m_2\),所以我们设两个标记\(mul\)表示乘,\(add\)表示加,然后如上转化。

代码:

#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100000 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 10007;
using namespace std;
ll n, m, p;
ll sum[maxn << 2], add[maxn << 2], mul[maxn << 2];
int a[maxn];
void pushup(int rt){
sum[rt] = (sum[rt << 1] + sum[rt << 1 | 1]) % p;
}
void pushdown(int rt, int l, int r){
int m = (l + r) >> 1;
sum[rt << 1] = (sum[rt << 1] * mul[rt] + add[rt] * (m - l + 1)) % p;
sum[rt << 1 | 1] = (sum[rt << 1 | 1] * mul[rt] + add[rt] * (r - m)) % p;
add[rt << 1] = (add[rt << 1] * mul[rt] + add[rt]) % p;
add[rt << 1 | 1] = (add[rt << 1 | 1] * mul[rt] + add[rt]) % p;
mul[rt << 1] = mul[rt << 1] * mul[rt] % p;
mul[rt << 1 | 1] = mul[rt << 1 | 1] * mul[rt] % p;
add[rt] = 0;
mul[rt] = 1;
}
void build(int l, int r, int rt){
add[rt] = 0;
mul[rt] = 1;
if(l == r){
sum[rt] = a[l];
return;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
pushup(rt);
}
void update(int L, int R, int l, int r, int v, int op, int rt){
if(L <= l && R >= r){
if(op == 2){
add[rt] = (add[rt] + v) % p;
sum[rt] = (sum[rt] + (r - l + 1) * v) % p;
}
else{
add[rt] = add[rt] * v % p;
mul[rt] = mul[rt] * v % p;
sum[rt] = sum[rt] * v % p;
}
return;
}
pushdown(rt, l, r);
int m = (l + r) >> 1;
if(L <= m)
update(L, R, l, m, v, op, rt << 1);
if(R > m)
update(L, R, m + 1, r, v, op, rt << 1 | 1);
pushup(rt);
}
ll query(int L, int R, int l, int r, int rt){
if(L <= l && R >= r){
return sum[rt];
}
pushdown(rt, l, r);
int m = (l + r) >> 1;
ll ret = 0;
if(L <= m)
ret += query(L, R, l, m, rt << 1);
if(R > m)
ret += query(L, R, m + 1, r, rt << 1 | 1);
return ret % p;
}
int main(){
scanf("%lld%lld%lld", &n, &m, &p);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(1, n, 1);
while(m--){
int op, x, y, k;
scanf("%d%d%d", &op, &x, &y);
if(op != 3) scanf("%d", &k);
if(op == 1) update(x, y, 1, n, k, 1, 1);
else if(op == 2) update(x, y, 1, n, k, 2, 1);
else printf("%lld\n", query(x, y, 1, n, 1));
}
return 0;
}

P3373 线段树2(多重标记线段树)题解的更多相关文章

  1. 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点

    题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...

  2. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  3. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  4. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

  5. 【BZOJ2402】陶陶的难题II 分数规划+树链剖分+线段树+凸包

    题解: 首先分数规划是很明显的 然后在于我们如何要快速要求yi-mid*xi的最值 这个是看了题解之后才知道的 这个是斜率的一个基本方法 我们设y=mid*x+z 那么显然我们可以把(x,y)插入到一 ...

  6. 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex

    题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...

  7. 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树

    正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...

  8. ACM-ICPC 2018 焦作赛区网络预赛 E Jiu Yuan Wants to Eat (树链剖分+线段树)

    题目链接:https://nanti.jisuanke.com/t/31714 题意:给你一棵树,初始全为0,有四种操作: 1.u-v乘x    2.u-v加x   3. u-v取反  4.询问u-v ...

  9. 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)

    线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...

  10. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

随机推荐

  1. js模仿京东首页的倒计时功能

    模仿京东首页的倒计时 我们学习了定时器,可以用定时器做一个倒计时,于是我模仿了京东首页倒计时. 先看看京东首页的倒计时. 思路: 如何倒计时? 给一个未来的时间.然后计算未来时间到现在的时间戳. 用定 ...

  2. jmeter-并发及常数吞吐量定时器设定

  3. e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks

    /Go/src/container/list/list.go:10

  4. Page not found (404) 不被Django的exception中间件捕捉 中间件

    Using the URLconf defined in config.urls, Django tried these URL patterns, in this order:

  5. Tensorflow-卷积神经网络CNN

    卷积神经网络CNN 结构 池化操作 手写数字-卷积神经网络实现 import tensorflow as tf from tensorflow.examples.tutorials.mnist imp ...

  6. Android webview 问题记录

    1. Android 7.1真机安装调试apk时报错,解析安装包失败 原因:sdk版本不支持7.1版本,需要调整minSdkVersion等参数,支持低版本 解决方法: android { compi ...

  7. Language Guide (proto3) | proto3 语言指南(十五)生成类

    Generating Your Classes - 生成类 要生成Java.Python.C++.Go.Ruby.ObjuleC或C代码,需要使用.proto文件中定义的消息类型,还需要在.proto ...

  8. 十二:SpringBoot-基于Cache注解模式,管理Redis缓存

    SpringBoot-基于Cache注解模式,管理Redis缓存 1.Cache缓存简介 2.核心API说明 3.SpringBoot整合Cache 3.1 核心依赖 3.2 Cache缓存配置 3. ...

  9. SpringMVC 中 @ControllerAdvice 注解

    SpringMVC 中 @ControllerAdvice 注解 1.@ControllerAdvice 1.1 全局异常处理 1.2 全局数据绑定 1.3 全局数据预处理 原文地址: 江南一点雨:S ...

  10. sql 工具类function

    --判断是否为整数 create or replace function is_number(param VARCHAR2) return NUMBER is v_num NUMBER; begin ...