题意:

有长为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]维护序列 区间加乘模板的更多相关文章

  1. 洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)

    洛谷P2023 [AHOI2009]维护序列 区间修改 当我们要修改一个区间时,要保证 \(ax+b\) 的形式,即先乘后加的形式.当将区间乘以一个数 \(k\) 时,原来的区间和为 \(ax+b\) ...

  2. 洛谷P3373 【模板】线段树 2 && P2023 [AHOI2009]维护序列——题解

    题目传送: P3373 [模板]线段树 2  P2023 [AHOI2009]维护序列 该题较传统线段树模板相比多了一个区间乘的操作.一提到线段树的区间维护问题,就自然想到了“懒标记”:为了降低时间复 ...

  3. 洛谷 P2023 [AHOI2009]维护序列 题解

    P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...

  4. 洛谷 P2023 [AHOI2009]维护序列

    P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中 ...

  5. P2023 [AHOI2009]维护序列 题解(线段树)

    题目链接 P2023 [AHOI2009]维护序列 解题思路 线段树板子.不难,但是...有坑.坑有多深?一页\(WA\). 由于乘法可能乘\(k=0\),我这种做法可能会使结果产生负数.于是就有了这 ...

  6. [洛谷P2023] [AHOI2009]维护序列

    洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...

  7. 【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)

    洛谷P2023:https://www.luogu.org/problemnew/show/P2023 思路 需要2个Lazy-Tag 一个表示加的 一个表示乘的 需要先计算乘法 再计算加法 来自你谷 ...

  8. [P2023][AHOI2009]维护序列(线段树)

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  9. 【luogu P2023 [AHOI2009]维护序列】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2023 把P3373改一改直接粘过来就A #include <iostream> #include ...

随机推荐

  1. Ubuntu系统Apache2部署SSL证书

    参考链接: https://help.aliyun.com/document_detail/102450.html?spm=a2c4g.11186623.6.582.17b74c07mBaXWS

  2. 网页出现横向滚动条的原因可能是使用bootstrap不当引起

    Bootstrap的栅格布局超级方便我们写网页.但是在不是全体配合使用的情况下,会出现横向滚动条的现象. 什么叫不是配合使用的情况呢? >>一种情况是:你使用了row作为你的第一层父元素: ...

  3. 最近公共祖先 Lowest Common Ancestors

    基于深度的LCA算法:  对于两个结点u.v,它们的深度分别为depth(u).depth(v),对于其公共祖先w,深度为depth(w),u需要向上回溯depth(u)-depth(w)步,v需要d ...

  4. SDOI2010 粟粟的书架 lg2468(可持久化,前缀和)

    题面见https://www.luogu.org/problemnew/show/P2468 然后这道题属于合二为一题,看一眼数据范围就能发现 首先我们先考虑50分,二维前缀和维护一下(反正我不记得公 ...

  5. 初识消息队列--ActiveMq

    消息队列 即MessageQueue,是一种消息中间件,在遇到系统请求量比较大的情况下,导致请求堆积过多无法及时返回,可以通过它进行异步的消息处理,从而缓解系统压力. ActiveMq ActiveM ...

  6. Token:服务端身份验证的流行方案

    01- 身份认证 服务端提供资源给客户端,但是某些资源是有条件的.所以服务端要能够识别请求者的身份,然后再判断所请求的资源是否可以给请求者. token是一种身份验证的机制,初始时用户提交账号数据给服 ...

  7. C++11 新用法

    基于哈希的 map 和 set 简述 基于哈希的 map 和 set ,它们分别叫做 unordered_map, unordered_set .数据分布越平均,性能相较 map 和 set 来说提升 ...

  8. JavaScript函数、对象和数组

    一.JavaScript函数 1.定义函数:函数的通用语法如下 function function_name([parameter [, ...]]) { statements; } 由关键字func ...

  9. getPath

    getPath()与getAbsolutePath()的区别 public void diff_pathAndAbsolutePath(){ File file1 = new File(“.\test ...

  10. JDBC——Statement执行SQL语句的对象

    Statement该对象用于执行静态SQL语句并返回它产生的结果.表示所有的参数在生成SQL的时候都是拼接好的,容易产生SQL注入的问题 PreparedStatement对象是一个预编译的SQL语句 ...