P2023 [AHOI2009]维护序列 区间加乘模板
题意:
有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式:N<=1e5
(1)把数列中的一段数全部乘一个值;
(2)把数列中的一段数全部加一个值;
(3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。
思路:
线段树,因为有可能存在,同时加和乘,所以lazy标记变为二维,一个记录乘,一个记录加
因为乘是总和乘一个数,所以先乘再加,这里需要注意,因为原本的区间和可能是zhi+lazy【加】,乘是总体,所以标记lazy【加】也要乘
il void pushdown(int x,ll mod,int l,int r){
if(lazy[x][]!=){
tree[x<<]*=lazy[x][];tree[x<<]%=mod;
tree[x<<|]*=lazy[x][];tree[x<<|]%=mod;
lazy[x<<][]*=lazy[x][];lazy[x<<][]%=mod;
lazy[x<<|][]*=lazy[x][];lazy[x<<|][]%=mod;
lazy[x<<][]*=lazy[x][];lazy[x<<][]%=mod;
lazy[x<<|][]*=lazy[x][];lazy[x<<|][]%=mod;
lazy[x][]=;
}
if(lazy[x][]!=){
int mid=(l+r)>>;
tree[x<<]+=(mid-l+)*lazy[x][];tree[x<<]%=mod;
tree[x<<|]+=(r-mid)*lazy[x][];tree[x<<|]%=mod;
lazy[x<<][]+=lazy[x][];lazy[x<<][]%=mod;
lazy[x<<|][]+=lazy[x][];lazy[x<<|][]%=mod;
lazy[x][]=;
}
}
pushdown操作
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define mem(a,b) memset(a,b,sizeof(a))
#define modd 998244353
const int maxn=2e5+;
int n,m,k;
ll p;
ll tree[maxn<<],lazy[maxn<<][],a[maxn];
il void pushdown(int x,ll mod,int l,int r){
if(lazy[x][]!=){
tree[x<<]*=lazy[x][];tree[x<<]%=mod;
tree[x<<|]*=lazy[x][];tree[x<<|]%=mod;
lazy[x<<][]*=lazy[x][];lazy[x<<][]%=mod;
lazy[x<<|][]*=lazy[x][];lazy[x<<|][]%=mod;
lazy[x<<][]*=lazy[x][];lazy[x<<][]%=mod;
lazy[x<<|][]*=lazy[x][];lazy[x<<|][]%=mod;
lazy[x][]=;
}
if(lazy[x][]!=){
int mid=(l+r)>>;
tree[x<<]+=(mid-l+)*lazy[x][];tree[x<<]%=mod;
tree[x<<|]+=(r-mid)*lazy[x][];tree[x<<|]%=mod;
lazy[x<<][]+=lazy[x][];lazy[x<<][]%=mod;
lazy[x<<|][]+=lazy[x][];lazy[x<<|][]%=mod;
lazy[x][]=;
}
}
il void pushup(int x,ll mod){
tree[x]=(tree[x<<]+tree[x<<|])%mod;
}
void build(int x,int l,int r,ll mod){
lazy[x][]=;lazy[x][]=;
if(l==r){
tree[x]=a[l];return;
}
int mid=(l+r)>>;
build(x<<,l,mid,mod);
build(x<<|,mid+,r,mod);
pushup(x,mod);
}
void updatej(int x,int l,int r,int l1,int r1,ll zhi,ll mod){
if(l1<=l && r<=r1){
pushdown(x,mod,l,r);
lazy[x][]=zhi;tree[x]+=(ll)(r-l+)*zhi;tree[x]%=mod;
return;
}
pushdown(x,mod,l,r);
int mid=(l+r)>>;
if(l1<=mid){
updatej(x<<,l,mid,l1,r1,zhi,mod);
}
if(r1>mid){
updatej(x<<|,mid+,r,l1,r1,zhi,mod);
}
pushup(x,mod);
}
void updatec(int x,int l,int r,int l1,int r1,ll zhi,ll mod){
if(l1<=l && r<=r1){
pushdown(x,mod,l,r);
lazy[x][]=zhi;tree[x]*=zhi;tree[x]%=mod;
return;
}
pushdown(x,mod,l,r);
int mid=(l+r)>>;
if(l1<=mid){
updatec(x<<,l,mid,l1,r1,zhi,mod);
}
if(r1>mid){
updatec(x<<|,mid+,r,l1,r1,zhi,mod);
}
pushup(x,mod);
}
ll query(int x,int l,int r,int l1,int r1,ll mod){
if(l1<=l && r<=r1){
return tree[x];
}
pushdown(x,mod,l,r);
int mid=(l+r)>>;
ll sum=;
if(l1<=mid){
sum+=query(x<<,l,mid,l1,r1,mod);sum%=mod;
}
if(r1>mid){
sum+=query(x<<|,mid+,r,l1,r1,mod);sum%mod;
}
return sum%mod;
}
int main(){
scanf("%d%lld",&n,&p);
for(it i=;i<=n;i++){
scanf("%lld",&a[i]);a[i]%=p;
}
build(,,n,p); scanf("%d",&m);
while(m--){//cout<<tree[1]<<endl;
int t,g;
ll c;
scanf("%d",&k);
if(k==){
scanf("%d%d%lld",&t,&g,&c);
updatec(,,n,t,g,c%p,p);
}
else if(k==){
scanf("%d%d%lld",&t,&g,&c);
updatej(,,n,t,g,c%p,p);
}
else{
scanf("%d%d",&t,&g);
printf("%lld\n",query(,,n,t,g,p));
}
}
return ;
}
这题也wa了好多遍,直到最后相通了,当加和乘同时存在的时候

P2023 [AHOI2009]维护序列 区间加乘模板的更多相关文章
- 洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)
洛谷P2023 [AHOI2009]维护序列 区间修改 当我们要修改一个区间时,要保证 \(ax+b\) 的形式,即先乘后加的形式.当将区间乘以一个数 \(k\) 时,原来的区间和为 \(ax+b\) ...
- 洛谷P3373 【模板】线段树 2 && P2023 [AHOI2009]维护序列——题解
题目传送: P3373 [模板]线段树 2 P2023 [AHOI2009]维护序列 该题较传统线段树模板相比多了一个区间乘的操作.一提到线段树的区间维护问题,就自然想到了“懒标记”:为了降低时间复 ...
- 洛谷 P2023 [AHOI2009]维护序列 题解
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...
- 洛谷 P2023 [AHOI2009]维护序列
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中 ...
- P2023 [AHOI2009]维护序列 题解(线段树)
题目链接 P2023 [AHOI2009]维护序列 解题思路 线段树板子.不难,但是...有坑.坑有多深?一页\(WA\). 由于乘法可能乘\(k=0\),我这种做法可能会使结果产生负数.于是就有了这 ...
- [洛谷P2023] [AHOI2009]维护序列
洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...
- 【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)
洛谷P2023:https://www.luogu.org/problemnew/show/P2023 思路 需要2个Lazy-Tag 一个表示加的 一个表示乘的 需要先计算乘法 再计算加法 来自你谷 ...
- [P2023][AHOI2009]维护序列(线段树)
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...
- 【luogu P2023 [AHOI2009]维护序列】 题解
题目链接:https://www.luogu.org/problemnew/show/P2023 把P3373改一改直接粘过来就A #include <iostream> #include ...
随机推荐
- 【你不知道的javaScript 上卷 笔记1】 javaScript 是如何工作的?
一.什么是作用域? 作用域是用来存储变量以及方便寻找变量的一套规则. 二.javaScript 编译过程(编译发生在代码执行前的几微妙) 分词/词法分析(Tokenizing/Lexing)-> ...
- [SDOI2017] 新生舞会 - 二分图最大权匹配,分数规划,二分答案
有一个二分图,每个部都有 \(n\) 个点,每条边有两个参数 \(a_e, b_e\),求一种匹配,使得 \(\sum a_i / \sum b_i\) 最大 Solution 显然的分数规划,考虑二 ...
- Linux C/C++ 字符串逆序
/*字符串逆序*/ #include <stdio.h> #include <string.h> void nixu(char *str) { ; char tmp; for( ...
- BOM笔记
目录 BOM (浏览器对象模型) 简介 window对象 子对象 history 子对象 lacation 子对象 navigator 子对象 screen 子对象 frames BOM (浏览器对象 ...
- Java学习笔记(十二)面向对象---内部类
内部类的访问规则 内部类可以直接访问外部类中的成员,包括私有成员. 因为内部类中持有了一个外部类的引用,格式为:外部类名.this 外部类要访问内部类,必须要建立内部对象. class Outer { ...
- javascript当中prototype用法
prototype见上一节,马克-to-win:prototype作用就是给某个类增加一个实例方法. 例 3.6.2 <head> <meta http-equiv=" ...
- C#中常见的winform控件命名规范 转
我们知道Button 常常简称为btn,那么Winform中的其它控件呢,这篇文章在C#的winform控件命名规范 的基础上对一些控件的名称的简称进行了整理. 1. 标准控件 NO. 控件类型简写 ...
- ModuleNotFoundError: No module named 'numpy.testing.nosetester'
- Java TreeSet集合 比较器排序Comparator的使用
比较器排序Comparator的使用 存储学生对象,并遍历,创建TreeSet集合使用带参构造方法 要求,按照学生年龄从小到大排序,如果年龄相同,则按照姓名的字母循序排序 结论 用TreeSet集合存 ...
- 题解【洛谷P5958】[POI2017]Sabotaż
题面 考虑树形 \(\text{DP}\). 设 \(dp_i\) 为使 \(i\) 变成叛徒的最大值,同时 \(dp_i\) 也是使 \(i\) 不变成叛徒的最小值. 然后考虑如何转移状态. 如果 ...