标签:
赤裸裸的线段树
#include<iostream> #include<cstdio> #include<algorithm> #define Max(a,b) (a>b)?a:b using namespace std; const int MAX_N=100005*4;//至少要开2*n-1个空间 typedef long long LL; struct node{ int l,r,max; LL sum; }; node a[MAX_N]; void build(int n,int l,int r) { a[n].l=l; a[n].r=r; a[n].max=-1; a[n].sum=0; if(l==r) { return ; } build(2*n,l,(l+r)/2); build(2*n+1,(l+r)/2+1,r); } void insert(int n, int pos,int val) { a[n].sum+=val; a[n].max=max(a[n].max,val); if(a[n].l==pos&&a[n].r==pos) { return ; } int mid=(a[n].l+a[n].r)/2; if(pos<=mid) insert(2*n,pos,val); else insert(2*n+1,pos,val); } void change(int n,int pos,int val) { if(a[n].l==pos&&a[n].r==pos) { a[n].max=val; a[n].sum=val; return ; } int mid=(a[n].l+a[n].r)/2; if(pos<=mid) change(2*n,pos,val); else change(2*n+1,pos,val); a[n].max=max(a[2*n].max,a[2*n+1].max); a[n].sum=a[2*n].sum+a[2*n+1].sum; } int Qmax(int n,int l,int r) { if(a[n].l==l&&a[n].r==r) { return a[n].max; } int mid=(a[n].l+a[n].r)/2; if(r<=mid) { return Qmax(2*n,l,r); } else if(mid<l) { return Qmax(2*n+1,l,r); } else { return Max(Qmax(2*n,l,mid),Qmax(2*n+1,mid+1,r)); } } LL Qsum(int n,int l, int r) { if(a[n].l==l&&a[n].r==r) { return a[n].sum; } int mid=(a[n].l+a[n].r)/2; if(r<=mid) { return Qsum(2*n,l,r); } else if(l>mid) { return Qsum(2*n+1,l,r); } return Qsum(2*n,l,mid)+Qsum(2*n+1,mid+1,r); } int main() { int n,m; scanf("%d %d",&n,&m); build(1,1,n); for(int i=1;i<=n;i++) { int v; scanf("%d",&v); insert(1,i,v); } while(m--) { int op,x,y; scanf("%d %d %d",&op,&x,&y); switch(op) { case 1:{ change(1,x,y); break; } case 2:{ printf("%lld\n",Qsum(1,x,y)); break; } case 3:{ printf("%d\n",Qmax(1,x,y)); break; } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/program-ccc/p/4938890.html