【BZOJ】1798 [Ahoi2009]Seq 维护序列seq
来源:互联网 发布:网络语rbq是什么意思 编辑:程序博客网 时间:2024/06/06 04:10
Description
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为
(1)把数列中的一段数全部乘一个值;
(3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模
Input
第一行两个整数
第二行含有
第三行有一个整数
从第四行开始每行描述一个操作,输入的操作有以下三种形式:
操作1:“1 t g c”(不含双引号)。表示把所有满足
操作2:“2 t g c”(不含双引号)。表示把所有满足
操作3:“3 t g”(不含双引号)。询问所有满足
Output
对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
Solution
很经典的线段树题目。这题的题点就在于乘法标记和加法标记的叠加。
假如规定一段区间同时有两个标记的时候是先乘后加,假设一段区间,值为a,乘法标记为mul,加法标记为add。
那么其真实值就为
现在来了一个新的加法标记
如果来了一个新的乘法标记
那么这样就很明显了,如果是加法,直接叠加就好,如果是乘法,就把乘法和加法标记同时乘上修改量即可。
#include<stdio.h>#include<cstring>#define M 131072typedef long long ll;int t[(M<<1)+2],tag[(M<<1)+2],a[(M<<1)+2],c,L,R,aim,ans,n,q,mod;inline void maintain(const int &k,const int &l,const int &r){ if (t[k]==1 && tag[k]==0) return; a[k]=((ll)a[k]*t[k]+(ll)tag[k]*(r-l+1)) % mod; if (l==r) {tag[k]=0,t[k]=1;return;} t[k<<1]=(ll)t[k]*t[k<<1] % mod,t[k<<1|1]=(ll)t[k<<1|1]*t[k] % mod; tag[k<<1]=(ll)tag[k<<1]*t[k] % mod,tag[k<<1|1]=(ll)tag[k<<1|1]*t[k] % mod; tag[k<<1]=(tag[k<<1]+tag[k]) % mod,tag[k<<1|1]=(tag[k<<1|1]+tag[k]) % mod; tag[k]=0,t[k]=1;}void mul(const int &k,const int &l,const int &r){ maintain(k,l,r); if (L<=l && r<=R){t[k]=(ll)t[k]*aim % mod;return;} int mid=(l+r)>>1; if (L<=mid) mul(k<<1,l,mid); if (mid<R) mul(k<<1|1,mid+1,r); maintain(k<<1,l,mid); maintain(k<<1|1,mid+1,r); a[k]=(a[k<<1]+a[k<<1|1]) % mod;}void add(const int &k,const int &l,const int &r){ maintain(k,l,r); if (L<=l && r<=R){tag[k]=(tag[k]+aim) % mod;return;} int mid=(l+r)>>1; if (L<=mid) add(k<<1,l,mid); if (mid<R) add(k<<1|1,mid+1,r); maintain(k<<1,l,mid); maintain(k<<1|1,mid+1,r); a[k]=(a[k<<1]+a[k<<1|1]) % mod;}void get(const int &k,const int &l,const int &r){ maintain(k,l,r); if (L<=l && r<=R) { if (l!=r) { int mid=(l+r)>>1; maintain(k<<1,l,mid); maintain(k<<1|1,mid+1,r); a[k]=(a[k<<1]+a[k<<1|1]) % mod; } ans=(ans+a[k]) % mod; return; } int mid=(l+r)>>1; if (L<=mid) get(k<<1,l,mid); if (mid<R) get(k<<1|1,mid+1,r);}int main(){ scanf("%d%d",&n,&mod); for (int i=0;i<n;i++) scanf("%d",a+M+i),a[M+i]%=mod; for (int i=M-1;i;i--) a[i]=(a[i<<1]+a[i<<1|1]) % mod; for (int i=1;i<M<<1;i++) t[i]=1; scanf("%d",&q); while (q--) { scanf("%d%d%d",&c,&L,&R); if (c==1) scanf("%d",&aim),aim%=mod,mul(1,1,M); if (c==2) scanf("%d",&aim),aim%=mod,add(1,1,M); if (c==3) ans=0,get(1,1,M),printf("%d\n",ans); }}
- 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 P1798:[Ahoi2009]Seq 维护序列seq
- UPD BZOJ 1798: [Ahoi2009]Seq 维护序列seq
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq|线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- GMM
- 网络流算法基础
- 数论Trailing Zeroes (III)light0j1138
- Unity Shader基础(3)--unity shader 常用语义
- 内存对齐原因
- 【BZOJ】1798 [Ahoi2009]Seq 维护序列seq
- 在js中if条件为null/undefined/0/NaN/""表达式时,统统被解释为false,此外均为true哦。。。(官方原文如下:)
- php生成XML文件
- Service生命周期调用
- 网络获取图片加入导航页
- java对象和xml之间转换--Jaxb--1
- Codeforces Round #377 (Div. 2)(A+B)
- 用一个栈来实现另一个栈的排序
- axure如何快速上手