bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树)
来源:互联网 发布:手机识图软件 编辑:程序博客网 时间:2024/05/15 10:00
题目描述
传送门
题目大意:有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值
题解
线段树维护加乘标记的裸题。。。
代码
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define N 400003#define LL long long using namespace std;int n,m,a[N];LL tr[N],add[N],mul[N],p;void update(int x){ tr[x]=(tr[x<<1]+tr[x<<1|1])%p;}void build(int now,int l,int r){ mul[now]=1; add[now]=0; if (l==r) { tr[now]=a[l]; mul[now]=1; return; } int mid=(l+r)/2; build(now<<1,l,mid); build(now<<1|1,mid+1,r); update(now);}void pushdown(int now,int l,int r){ int mid=(l+r)/2; if (mul[now]!=1) { tr[now<<1]=tr[now<<1]*mul[now]%p; tr[now<<1|1]=tr[now<<1|1]*mul[now]%p; mul[now<<1]=mul[now<<1]*mul[now]%p; mul[now<<1|1]=mul[now<<1|1]*mul[now]%p; add[now<<1]=add[now<<1]*mul[now]%p; add[now<<1|1]=add[now<<1|1]*mul[now]%p; mul[now]=1; } if (add[now]) { tr[now<<1]+=add[now]*(mid-l+1)%p; if (tr[now]>=p) tr[now]-=p; tr[now<<1|1]+=add[now]*(r-mid)%p; if (tr[now]>=p) tr[now]-=p; add[now<<1]+=add[now]; if (add[now]>=p) add[now]-=p; add[now<<1|1]+=add[now]; if (add[now]>=p) add[now]-=p; add[now]=0; }}void qjmul(int now,int l,int r,int ll,int rr,LL val){ if (ll<=l&&r<=rr) { tr[now]=tr[now]*val%p; mul[now]=mul[now]*val%p; add[now]=add[now]*val%p; return; } int mid=(l+r)/2; pushdown(now,l,r); if (ll<=mid) qjmul(now<<1,l,mid,ll,rr,val); if (rr>mid) qjmul(now<<1|1,mid+1,r,ll,rr,val); update(now);}void qjadd(int now,int l,int r,int ll,int rr,LL val){ if (ll<=l&&r<=rr) { tr[now]=(LL)(tr[now]+(LL)(r-l+1)*val%p); if (tr[now]>=p) tr[now]-=p; add[now]+=val; if (add[now]>=p) add[now]-=p; return; } int mid=(l+r)/2; pushdown(now,l,r); if (ll<=mid) qjadd(now<<1,l,mid,ll,rr,val); if (rr>mid) qjadd(now<<1|1,mid+1,r,ll,rr,val); update(now); //cout<<l<<" "<<r<<" "<<tr[now]<<endl;}LL qjsum(int now,int l,int r,int ll,int rr){ if (ll<=l&&r<=rr) return tr[now]; int mid=(l+r)/2; LL ans=0; pushdown(now,l,r); if (ll<=mid) ans+=qjsum(now<<1,l,mid,ll,rr); ans%=p; if (rr>mid) ans+=qjsum(now<<1|1,mid+1,r,ll,rr); ans%=p; return ans;}int main(){ freopen("a.in","r",stdin); //freopen("my.out","w",stdout); scanf("%d%lld",&n,&p); for (int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); scanf("%d",&m); for (int i=1;i<=m;i++) { int opt,x,y,z; scanf("%d%d%d",&opt,&x,&y); if (opt==2) { scanf("%d",&z); qjadd(1,1,n,x,y,z); // cout<<tr[1]<<endl; } if (opt==1) { scanf("%d",&z); qjmul(1,1,n,x,y,z); } if (opt==3) { printf("%lld\n",qjsum(1,1,n,x,y)%p); } }}
0 0
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq|线段树
- 【BZOJ】1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq 线段树题解
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树模板
- bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树乘法加法的混合操作)
- BZOJ 题目1798: [Ahoi2009]Seq 维护序列seq(双标记线段树)
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq
- bzoj 1798: [Ahoi2009]Seq 维护序列seq
- 【BZOJ 1798】 [Ahoi2009]Seq 维护序列seq
- bzoj 1798 [Ahoi2009]Seq 维护序列seq
- 【BZOJ 1798】[Ahoi2009]Seq 维护序列seq
- [BZOJ 1798][Ahoi2009]Seq 维护序列seq
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq
- NYOJ 华山论剑
- python调用
- SWERC'2016 F 树形DP+树状数组
- Web前端-对index()的理解
- 字符拼接StringBuilder速度快,但StringBuilder是线程不安全的。(StringBuffer是线程安全的,给buffer加锁)
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- webLogic 安装和项目部署图解
- php里面对时间上的处理问题
- 基本数据类型在32位系统和64位系统中所占字节数
- 通过网络结构估算caffemodel文件的大小
- 120-epoll(边沿模式)
- 112. Path Sum
- Java中 Serializable的使用
- 4Sum