P3373 线段树2(多重标记线段树)题解
题意:
操作有:区间加,区间乘,区间询问求和
思路:
设一个数为\(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(多重标记线段树)题解的更多相关文章
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- 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 ...
- 主席树[可持久化线段树](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 ...
- 【BZOJ2402】陶陶的难题II 分数规划+树链剖分+线段树+凸包
题解: 首先分数规划是很明显的 然后在于我们如何要快速要求yi-mid*xi的最值 这个是看了题解之后才知道的 这个是斜率的一个基本方法 我们设y=mid*x+z 那么显然我们可以把(x,y)插入到一 ...
- 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex
题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 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 ...
- 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)
线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...
- hdu 3966(树链剖分+线段树区间更新)
传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...
随机推荐
- Nginx基础环境搭建
1.下载docker toolbox https://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ 2.选择好安装目录 一路nex ...
- 前端知识(二)08-Vue.js的路由-谷粒学院
目录 一.锚点的概念 二.路由的作用 三.路由实例 1.复制js资源 2.创建 路由.html 3.引入js 4.编写html 5.编写js 一.锚点的概念 案例:百度百科 特点:单页Web应用,预先 ...
- 使用amoeba实现mysql读写分离
使用amoeba实现mysql读写分离 1.什么是amoeba? Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发.座落与Client.DB Server(s)之间.对客户端透明. ...
- Bitter ORM NETCORE ORM 全网最粗暴简单易用高性能的 NETCore ORM 开源了
开源的来了,懒人程序员的福音,.NET 生态闭环太缺开源精神了, 拥抱开源! 前言: 本人不是不喜欢现有ORM的轮子,而是发现现有的ORM 的都不太符合开发人员的一些习惯.现有的ORM 要么功能太冗余 ...
- code-server scala error: object apache is not a member of package org
原因是scala缺少包,需要把spark或对应的包放入scala目录下的lib,然后重启主机,在terminal输入reboot即可. 如果不重启主机,则在交互式编程中可以成功import.但是直接在 ...
- bcprov-jdk15on包用于创建CSR(证书请求)
<!-- Eureka注册中心客户端依赖 --> <dependency> <groupId>org.springframework.cloud</group ...
- SparkMLlib—协同过滤推荐算法,电影推荐系统,物品喜好推荐
SparkMLlib-协同过滤推荐算法,电影推荐系统,物品喜好推荐 一.协同过滤 1.1 显示vs隐式反馈 1.2 实例介绍 1.2.1 数据说明 评分数据说明(ratings.data) 用户信息( ...
- Spark JDBC方式连接MySQL数据库
Spark JDBC方式连接MySQL数据库 一.JDBC connection properties(属性名称和含义) 二.spark jdbc read MySQL 三.jdbc(url: Str ...
- Spring boot 自定义注解标签记录系统访问日志
package io.renren.common.annotation; import java.lang.annotation.Documented; import java.lang.annota ...
- SealClient
import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import ja ...