Description
河蟹王国有一位河蟹国王,他的名字叫羊驼。河蟹王国富饶安定,人们和谐相处。有一天,羊驼国王心血来潮,想在一部分人中挑出最和谐的人。于是,羊驼国王将他的子民排成了一列(==!!b汗~好长呀)。每个人都有一个初始的和谐值。羊驼国王每次会选择一个区间[L,R],这个区间中和谐值最大的人就是国王选出的人。而且,在某一时间,区间[L',R']里的人会变得熟悉,因此他们每个人的和谐值都会上升一个相同的值C。羊驼国王想知道,对于每一次选择,他选出的最大和谐值是多少。
Input
第一行是一个数N(1<=N<=100000),表示人数。
接下来的N行,每行一个数,表示排成的序列第i个人和谐值的初始值。
接下来是一个数M(1<=M<=100000),表示羊驼国王或他的子民有所活动(羊驼国王选择一个区间算一次,某区间里的人增长和谐值算一次)的总次数。
接下来的M行,每行第一个是一个数K,K是1或2,若K=1,接下来有三个数L,R,C,表示区间[L,R]的所有人增加C的和谐值;若K=2,接下来有两个数L,R,表示国王选择了区间[L,R]。
Output
每次对于国王选择区间,输出选择区间里的最大和谐值。
Sample Input
5 1 2 3 4 5 3 2 1 4 1 1 3 3 2 3 5
Sample Output
4 6
HINT
每个测试点1s。
保证所有的数以及结果都在longint范围内。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn=100010; int cnt=0; int a[maxn]; struct treetype{ int lptr,rptr; int Left,Right; int mx,bj; //区间最大值 }t[2*maxn]; void buildtree(int ll,int rr){ int cur=++cnt; t[cur].Left=ll; t[cur].Right=rr; if (ll!=rr-1){ t[cur].lptr=cnt+1; buildtree(ll,(ll+rr)/2); t[cur].rptr=cnt+1; buildtree((ll+rr)/2,rr); t[cur].mx=max(t[t[cur].lptr].mx,t[t[cur].rptr].mx); t[cur].bj=0; }else{ t[cur].mx=a[ll]; t[cur].bj=0; } } void update(int k){ if (t[k].Right-1 != t[k].Left){ t[t[k].lptr].mx+=t[k].bj; t[t[k].rptr].mx+=t[k].bj; t[t[k].lptr].bj+=t[k].bj; t[t[k].rptr].bj+=t[k].bj; } t[k].bj=0; } void change(int k,int ll,int rr,int delta){ if (t[k].bj) update(k); if (ll<=t[k].Left && rr>=t[k].Right){ t[k].mx+=delta; t[k].bj+=delta; } else{ if (ll<(t[k].Left+t[k].Right)/2) change(t[k].lptr,ll,rr,delta); if (rr>(t[k].Left+t[k].Right)/2) change(t[k].rptr,ll,rr,delta); t[k].mx=max(t[t[k].lptr].mx,t[t[k].rptr].mx); //↑更新 } } int query(int k,int ll,int rr){ if (t[k].bj) update(k); if(ll<=t[k].Left && rr>=t[k].Right) return t[k].mx; int ans=-10000000; //有负数 if (ll<(t[k].Left+t[k].Right)/2) ans=query(t[k].lptr,ll,rr); if (rr>(t[k].Left+t[k].Right)/2) ans=max(ans,query(t[k].rptr,ll,rr)); return ans; } int main(){ int n,m,type,lf,rt,del; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); buildtree(1,n+1); int i=1; for (i=1;i<=m;i++){ scanf("%d",&type); if (type==1){ scanf("%d%d%d",&lf,&rt,&del); change(1,lf,rt+1,del); } else{ scanf("%d%d",&lf,&rt); printf("%d\n",query(1,lf,rt+1)); } } return 0; }