1. 程式人生 > >線段樹求區間最大值+區間更新+區間求和+lazy標記

線段樹求區間最大值+區間更新+區間求和+lazy標記

馬上就省賽了,線段樹還缺個求區間最大值的板子,百度,Google全都是一個板子,而且還沒有lazy標記,樸素更新,好氣啊
區間最小值也同理
lazy的我只能自己寫
藍瘦香菇
code:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<string>
#include <set>
using namespace std;
#define ll long long
#define mem(a) memset(a,0,sizeof(a)) const int eps=1e-8; const int maxn=30010;//須填寫 const int inf=0x3f3f3f3f; int n,m; struct node//定義結構體儲存線段樹 { int l; int r; ll ma; ll sum; ll mark; }s[300000]; void pushup(int k)//求和與最大值 { s[k].sum=s[k<<1].sum+s[(k<<1)+1].sum; s[k].ma=max(s[k<<1
].ma,s[(k<<1)+1].ma); } void pushdown(int k,int d)//標記下移 { if(s[k].mark) { s[k<<1].mark+=s[k].mark; s[(k<<1)+1].mark+=s[k].mark; s[k<<1].sum+=s[k].mark*(d-(d>>1)); //s[k<<1].ma+=s[k].mark; s[(k<<1)+1].sum+=s[k].mark*(d>>1
); //s[(k<<1)+1].ma+=s[k].mark; s[k].mark=0; } } void init(int l,int r,int k) { s[k].l=l; s[k].r=r; s[k].mark=0; s[k].ma=0; if(l==r) { scanf("%lld",&s[k].sum); s[k].ma=s[k].sum; //cout<<"輸入成功"<<endl; return ; } int mid=(l+r)/2; init(l,mid,k<<1); init(mid+1,r,(k<<1)+1); pushup(k); } ll query(int l,int r,int k) { if(l<=s[k].l&&r>=s[k].r) { return s[k].sum; } pushdown(k,s[k].r-s[k].l+1); int mid=(s[k].l+s[k].r)/2; long long res=0; if(l<=mid) res+=query(l,r,(k<<1)); if(r>mid) res+=query(l,r,(k<<1)+1); return res; } ll queryma(int l,int r,int k)//查詢最大值 { if(l<=s[k].l&&r>=s[k].r) { return s[k].ma; } pushdown(k,s[k].r-s[k].l+1); int mid=(s[k].l+s[k].r)/2; long long resa=0; long long resb=0; if(l<=mid) resa=queryma(l,r,(k<<1)); if(r>mid) resb=queryma(l,r,(k<<1)+1); return max(resa,resb); } void update(int l,int r,int c,int k) { if(l<=s[k].l&&r>=s[k].r) { s[k].mark+=c; s[k].sum+=(c*(s[k].r-s[k].l+1)); s[k].ma+=c; return ; } pushdown(k,s[k].r-s[k].l+1); int mid=(s[k].l+s[k].r)/2; if(l<=mid) update(l,r,c,k<<1); if(r>mid) update(l,r,c,(k<<1)+1); pushup(k); }