题意:

有长为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. python接口

    用正则表达式提取数据: https://www.cnblogs.com/dwdw/p/9553192.html python unittest TestCase间共享数据(全局变量的使用): http ...

  2. nginx配置之后接口状态200,但是无返回数据问题小记

    nginx配置可能有问题.导致nginx不能解析PHP文件,检测nginx里对于php的配置信息. location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; f ...

  3. Docker学习一篇就够了

    Docker 1.简介 Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像 ...

  4. android获取系统信息

    连接手机,adb shell 进入 Android Shell 模式,输入 getprop 获取系统属性值 通过上面方法拿到属性名,然后通过下面方法获取到系统的属性值 /** * 获取build.pr ...

  5. python面试的100题(13)

    29.Given an array of integers 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数.你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用.示例:给定nums ...

  6. lamda表达式的两种写法

    public class Test{ public synchronized void test1(){ System.out.println("test1 start........... ...

  7. Pytest学习6-跳过或xfail失败的用例

    Skip跳过用例 跳过(Skip)指,你希望如果某些条件得到满足你的测试用例才执行,否则Pytest应该完全跳过运行该用例 1. 跳过测试用例的最简单方法是使用skip装饰器标记它,可以传递一个可选的 ...

  8. [WC2006] 水管局长 - Link Cut Tree

    离线后逆序处理所有操作,那么就变成了加边询问,根据MST的性质,显然维护MST询问链上max即可 #include <bits/stdc++.h> using namespace std; ...

  9. LocalDate和LocalTime的用法介绍

    原文:LocalDate和LocalTime的用法介绍 在JAVA中,常用的处理日期和时间的类主要有Date,Calendar,而在JDK1.8中,新增了两个处理日期和时间的类,一个是LocalDat ...

  10. .Net中C# Dictionary 用法

    Dictionary提供快速的基于键值的元素查找. 结构是:Dictionary <[key] , [value] >,当你有很多元素的时候可以用它. 它包含在System.Collect ...