线段树模板
2018-02-05 19:24
127 查看
区间和
#include<cstdio> #define ll long long const int MAXN=100010; struct Tree { #define lson (o<<1) #define rson (o<<1|1) #define l(x) tree[x].l #define r(x) tree[x].r #define sum(x) tree[x].sum #define add(x) tree[x].add ll sum,add; int l,r; } tree[MAXN<<2]; ll a[MAXN]; void build(int o,int l,int r) { l(o)=l,r(o)=r; add(o)=0; if(l==r) { sum(o)=a[l]; return; } int mid=(l(o)+r(o))>>1; if(l<=mid)build(lson,l,mid); if(r>mid)build(rson,mid+1,r); sum(o)=sum(lson)+sum(rson); } void spread(int o) { if(add(o)) { sum(lson)+=add(o)*(r(lson)-l(lson)+1); sum(rson)+=add(o)*(r(rson)-l(rson)+1); add(lson)+=add(o); add(rson)+=add(o); add(o)=0; } } void change(int o,int l,int r,ll d) { if(l<=l(o)&&r(o)<=r) { add(o)+=d; sum(o)+=d*(r(o)-l(o)+1); return; } spread(o); int mid=(l(o)+r(o))>>1; if(l<=mid)change(lson,l,r,d); if(r>mid)change(rson,l,r,d); sum(o)=sum(lson)+sum(rson); return; } ll ask(int o,int l,int r) { if(l<=l(o)&&r(o)<=r)return sum(o); spread(o); int mid=(l(o)+r(o))>>1; ll val=0; if(l<=mid)val+=ask(lson,l,r); if(r>mid)val+=ask(rson,l,r); return val; } inline ll read(){ char ch=getchar(),f=1; ll x=0; while(ch<'0'||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return f*x; } inline void write(ll x){ if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); } inline void wrln(ll x){ write(x); putchar('\n'); } int main() { int n,m; n=read();m=read(); for(int i=1; i<=n; i++)scanf("%d",&a[i]); build(1,1,n); for(int i=1; i<=m; i++) { ll op,x,y,k; op=read();x=read();y=read(); if(op==1) { k=read(); change(1,x,y,k); } else wrln(ask(1,x,y)); } return 0; }
区间积与和
#include<cstdio> const int N=100100; #define LL long long LL p; struct Tree{ int l,r; LL sum,add,mul; #define sum(x) tree[x].sum #define add(x) tree[x].add #define mul(x) tree[x].mul #define l(x) tree[x].l #define r(x) tree[x].r #define lch (o<<1) #define rch (o<<1|1) }tree[N<<2]; int a ; void build(int o,int l,int r){ add(o)=sum(o)=0,mul(o)=1,l(o)=l,r(o)=r; if(l==r){ sum(o)=a[l]; return ; } int mid=(l+r)>>1; if(l<=mid)build(lch,l,mid); if(r>mid)build(rch,mid+1,r); sum(o)=(sum(lch)+sum(rch))%p; } void spread(int o){ sum(lch)=(sum(lch)*mul(o)+add(o)*(r(lch)-l(lch)+1))%p; sum(rch)=(sum(rch)*mul(o)+add(o)*(r(rch)-l(rch)+1))%p; add(lch)=(add(lch)*mul(o)+add(o))%p; add(rch)=(add(rch)*mul(o)+add(o))%p; mul(lch)=(mul(lch)*mul(o))%p; mul(rch)=(mul(rch)*mul(o))%p; add(o)=0; mul(o)=1; } void change(int o,int l,int r,LL add,LL mul){ if(l<=l(o)&&r>=r(o)){ sum(o)=(sum(o)*mul+(r(o)-l(o)+1)*add)%p; add(o)=(add(o)*mul+add)%p; mul(o)=(mul(o)*mul)%p; return ; } spread(o); int mid=(l(o)+r(o))>>1; if(l<=mid)change(lch,l,r,add,mul); if(r>mid)change(rch,l,r,add,mul); sum(o)=(sum(lch)+sum(rch))%p; } LL ask(int o,int l,int r){ if(l<=l(o)&&r>=r(o)) return sum(o); spread(o); int mid=(l(o)+r(o))>>1; LL val=0; if(l<=mid)val=(val+ask(lch,l,r))%p; if(r>mid)val=(val+ask(rch,l,r))%p; return val; } int main(){ int n,m,op,x,y; LL k; scanf("%d%d%lld",&n,&m,&p); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); for(int i=1;i<=m;i++){ scanf("%d%d%d",&op,&x,&y); if(op==3)printf("%lld\n",ask(1,x,y)); else{ scanf("%lld",&k); if(op==1)change(1,x,y,0,k); if(op==2)change(1,x,y,k,1); } } return 0; }
相关文章推荐
- AHOI 2009 行星序列 BZOJ 1798 COGS 1272 线段树模板题:加、乘标记
- (线段树)模板
- 线段树模板(结构体和非结构体写法)hdu1754
- ACM_模板_线段树
- POJ 3468 A Simple Problem with Integers 线段树区间更新 纯模板题
- 线段树 自己总结的模板
- P3373 【模板】线段树 2
- 线段树模板
- 【模板】主席树/函数式线段树/可持久化线段树
- FZU Problem 2171 防守阵地 II (线段树区间更新模板题)
- NYOJ 1185-最大最小值【线段树:模板--学习ing】
- 算法模板——线段树4(区间加+区间乘+区间覆盖值+区间求和)
- [模板]线段树
- HDU 1166-敌兵布阵【树状数组&&线段树单点更新】【模板】
- 线段树(模板)
- 线段树 面积并 模板题
- hdu 4578 线段树模板
- 树状数组、线段树模板(一)——单点更新 + HDU 1166 敌兵布阵
- codevs 1082 线段树练习3 模板题
- 洛谷 2068 线段树模板:单点更新,区间求和