【模板】线段树
RT,本人自己写的线段树,支持区修区查和RMQ。
//By lzj #include <cstdio> #define ri register int #define ls p<<1 #define rs p<<1|1 #define int long long #define INF 1e15 using namespace std; const int N=1e6+15; struct node{ int l,r; int tag1,tag2; int sum,maxn,minn; }tree[N<<2]; inline int read(){ int f=1; int num=0; char ch=getchar(); while(ch<'0'||ch>'9'){f|=(ch=='-'?-1:1);ch=getchar();} while(ch>='0'&&ch<='9'){num=(num<<1)+(num<<3)+(ch^48); ch=getchar();} return num*f; } void write(int x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } int max(int a,int b){ return a>b?a:b; } int min(int a,int b){ return a<b?a:b; } int n,q,op,x,y,z; int a[N]; void pushup(int p){ tree[p].sum=tree[ls].sum+tree[rs].sum; tree[p].maxn=max(tree[ls].maxn,tree[rs].maxn); tree[p].minn=min(tree[ls].minn,tree[rs].minn); } void pushdown(int p){ if(tree[p].tag1!=-INF){ tree[ls].tag1=tree[rs].tag1=tree[p].tag1; tree[ls].maxn=tree[p].tag1; tree[rs].maxn=tree[p].tag1; tree[ls].minn=tree[p].tag1; tree[rs].minn=tree[p].tag1; tree[ls].sum=tree[p].tag1*(tree[ls].r-tree[ls].l+1); tree[rs].sum=tree[p].tag1*(tree[rs].r-tree[rs].l+1); tree[ls].tag2=tree[rs].tag2=0; tree[p].tag1=-INF; } if(tree[p].tag2){ tree[ls].tag2+=tree[p].tag2; tree[rs].tag2+=tree[p].tag2; tree[ls].maxn+=tree[p].tag2; tree[rs].maxn+=tree[p].tag2; tree[ls].minn+=tree[p].tag2; tree[rs].minn+=tree[p].tag2; tree[ls].sum+=tree[p].tag2*(tree[ls].r-tree[ls].l+1); tree[rs].sum+=tree[p].tag2*(tree[rs].r-tree[rs].l+1); tree[p].tag2=0; } } void build(int p,int l,int r){ tree[p].l=l;tree[p].r=r; tree[p].tag1=-INF;tree[p].tag2=0; if(l==r){ tree[p].sum=tree[p].minn=tree[p].maxn=a[l]; return; } int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(p); } void update1(int p,int l,int r,int delta){ if(l<=tree[p].l&&tree[p].r<=r){ tree[p].sum=delta*(tree[p].r-tree[p].l+1); tree[p].maxn=tree[p].minn=delta; tree[p].tag1=delta; tree[p].tag2=0; return; } pushdown(p); int mid=(tree[p].l+tree[p].r)>>1; if(l<=mid) update1(ls,l,r,delta); if(r>mid) update1(rs,l,r,delta); pushup(p); } void update2(int p,int l,int r,int delta){ if(l<=tree[p].l&&tree[p].r<=r){ tree[p].maxn+=delta; tree[p].minn+=delta; tree[p].sum+=(tree[p].r-tree[p].l+1)*delta; tree[p].tag2+=delta; return; } pushdown(p); int mid=(tree[p].l+tree[p].r)>>1; if(l<=mid) update2(ls,l,r,delta); if(r>mid) update2(rs,l,r,delta); pushup(p); } int qmax(int p,int l,int r){ if(l<=tree[p].l&&tree[p].r<=r){ return tree[p].maxn; } pushdown(p); int mid=(tree[p].l+tree[p].r)>>1,val=-INF; if(l<=mid) val=max(val,qmax(ls,l,r)); if(r>mid) val=max(val,qmax(rs,l,r)); return val; } int qmin(int p,int l,int r){ if(l<=tree[p].l&&tree[p].r<=r){ return tree[p].minn; } pushdown(p); int mid=(tree[p].l+tree[p].r)>>1,val=INF; if(l<=mid) val=min(val,qmin(ls,l,r)); if(r>mid) val=min(val,qmin(rs,l,r)); return val; } int query(int p,int l,int r){ if(l<=tree[p].l&&tree[p].r<=r){ return tree[p].sum; } pushdown(p); int mid=(tree[p].l+tree[p].r)>>1,val=0; if(l<=mid) val+=query(ls,l,r); if(r>mid) val+=query(rs,l,r); return val; } signed main(){ n=read(); q=read(); for(ri i=1;i<=n;i++) a[i]=read(); build(1,1,n); while(q--){ op=read(); if(op==1){ x=read(); y=read(); z=read(); update1(1,x,y,z); } if(op==2){ x=read(); y=read(); z=read(); update2(1,x,y,z); } if(op==3){ x=read(); y=read(); write(qmax(1,x,y)); putchar('\n'); } if(op==4){ x=read(); y=read(); write(qmin(1,x,y)); putchar('\n'); } if(op==5){ x=read(); y=read(); write(query(1,x,y)); putchar('\n'); } } return 0; }