BZOJ 1798: [Ahoi2009]Seq 维护序列seq
2014-02-19 13:29
351 查看
题目地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1798
题目大意:维护一个序列,提供区间加、区间乘、区间询问操作。
算法讨论:
线段树模板题。
由于要处理加和乘2个操作,所以在下传标记时需要注意处理完整。我的做法是先处理乘标记,再处理加标记。处理乘标记时对其子节点的加、乘、答案标记都进行处理,处理加标记时对其子节点的加、答案标记进行处理。
由于可能乘0,所以乘标记为空是置为-1。
此题细节比较多,所以需要注意细节。
Code:
By Charlie Pan
Feb 19,2014
题目大意:维护一个序列,提供区间加、区间乘、区间询问操作。
算法讨论:
线段树模板题。
由于要处理加和乘2个操作,所以在下传标记时需要注意处理完整。我的做法是先处理乘标记,再处理加标记。处理乘标记时对其子节点的加、乘、答案标记都进行处理,处理加标记时对其子节点的加、答案标记进行处理。
由于可能乘0,所以乘标记为空是置为-1。
此题细节比较多,所以需要注意细节。
Code:
/* * Problem:1798 * Author:PYC */ #include <cstdio> #define maxn 100000 using namespace std; int n,p,a[maxn+1]; long long sum[maxn*4],_plus[maxn*4],_mul[maxn*4]; inline void up(int k){sum[k]=(sum[k*2]+sum[k*2+1])%p;} inline void down(int k,int len1,int len2){ if (_mul[k]>=0){ if (_mul[k*2]>=0) _mul[k*2]=(_mul[k*2]*_mul[k])%p;else _mul[k*2]=_mul[k]%p; if (_mul[k*2+1]>=0) _mul[k*2+1]=(_mul[k*2+1]*_mul[k])%p;else _mul[k*2+1]=_mul[k]%p; _plus[k*2]=(_plus[k*2]*_mul[k])%p; _plus[k*2+1]=(_plus[k*2+1]*_mul[k])%p; sum[k*2]=(sum[k*2]*_mul[k])%p; sum[k*2+1]=(sum[k*2+1]*_mul[k])%p; _mul[k]=-1; } if (_plus[k]){ _plus[k*2]=(_plus[k*2]+_plus[k])%p; _plus[k*2+1]=(_plus[k*2+1]+_plus[k])%p; sum[k*2]=(sum[k*2]+_plus[k]*len1%p)%p; sum[k*2+1]=(sum[k*2+1]+_plus[k]*len2%p)%p; _plus[k]=0; } } void build(int k,int lc,int rc){ if (lc==rc){sum[k]=a[lc];_mul[k]=-1;return;} int mid=(lc+rc)/2; build(k*2,lc,mid); build(k*2+1,mid+1,rc); up(k); _mul[k]=-1; } void plus(int k,int lc,int rc,int l,int r,int d){ if (lc==l && rc==r){sum[k]=(sum[k]+(r-l+1)*d%p)%p;_plus[k]=(_plus[k]+d)%p;return;} int mid=(lc+rc)/2; down(k,mid-lc+1,rc-mid); if (r<=mid) plus(k*2,lc,mid,l,r,d); else if (l>mid) plus(k*2+1,mid+1,rc,l,r,d); else{plus(k*2,lc,mid,l,mid,d);plus(k*2+1,mid+1,rc,mid+1,r,d);} up(k); } void mul(int k,int lc,int rc,int l,int r,int d){ if (lc==l && rc==r){ _plus[k]=(_plus[k]*d)%p; sum[k]=(sum[k]*d)%p; if (_mul[k]>=0) _mul[k]=(_mul[k]*d)%p;else _mul[k]=d%p; return; } int mid=(lc+rc)/2; down(k,mid-lc+1,rc-mid); if (r<=mid) mul(k*2,lc,mid,l,r,d); else if (l>mid) mul(k*2+1,mid+1,rc,l,r,d); else{mul(k*2,lc,mid,l,mid,d);mul(k*2+1,mid+1,rc,mid+1,r,d);} up(k); } long long ask(int k,int lc,int rc,int l,int r){ if (lc==l && rc==r) return sum[k]; int mid=(lc+rc)/2; down(k,mid-lc+1,rc-mid); if (r<=mid) return ask(k*2,lc,mid,l,r); if (l>mid) return ask(k*2+1,mid+1,rc,l,r); return (ask(k*2,lc,mid,l,mid)+ask(k*2+1,mid+1,rc,mid+1,r))%p; up(k); } int main(){ scanf("%d%d",&n,&p); for (int i=1;i<=n;++i) scanf("%d",&a[i]); build(1,1,n); int m; scanf("%d",&m); for (int i=1;i<=m;++i){ int x; scanf("%d",&x); if (x==1){ int l,r,d; scanf("%d%d%d",&l,&r,&d); mul(1,1,n,l,r,d); } if (x==2){ int l,r,d; scanf("%d%d%d",&l,&r,&d); plus(1,1,n,l,r,d); } if (x==3){ int l,r; scanf("%d%d",&l,&r); printf("%lld\n",ask(1,1,n,l,r)); } } return 0; }
By Charlie Pan
Feb 19,2014
相关文章推荐
- 线段树题集
- 线段树
- poj 2352
- SPOJ GSS1 Can you answer these queries I
- SPOJ GSS3 Can you answer these queries III
- SPOJ GSS3 Can you answer these queries III
- SPOJ GSS3 Can you answer these queries III
- SPOJ GSS3 Can you answer these queries III
- [bzoj1003] [ZJOI2006]物流运输trans
- [bzoj1500][NOI2005]维修数列
- [bzoj1208] [HNOI2004]宠物收养所
- [bzoj1269][AHOI2006]文本编辑器editort
- [bzoj1503][NOI2004]郁闷的出纳员
- 蓝桥杯:操作格子
- Binary Simulation 解题报告--线段树
- poj3468- A Simple Problem with Integers-解题报告-线段树
- BZOJ 3180 coci2012 ograda
- HDU 3016
- HDU 3071 Gcd & Lcm game
- hdu 1542(线段树 求矩形面积并)Atlantis