[Vijos] 河蟹王國

描述

河蟹王國有一位河蟹國王,他的名字叫羊駝。河蟹王國富饒安定,人們和諧相處。有一天,羊駝國王心血來潮,想在一部分人中挑出最和諧的人。因而,羊駝國王將他的子民排成了一列(==!!b汗~好長呀)。每一個人都有一個初始的和諧值。羊駝國王每次會選擇一個區間[L,R],這個區間中和諧值最大的人就是國王選出的人。並且,在某一時間,區間[L',R']裏的人會變得熟悉,所以他們每一個人的和諧值都會上升一個相同的值C。羊駝國王想知道,對於每一次選擇,他選出的最大和諧值是多少。測試

格式

輸入格式

第一行是一個數N(1<=N<=100000),表示人數。ui

接下來的N行,每行一個數,表示排成的序列第i我的和諧值的初始值。spa

接下來是一個數M(1<=M<=100000),表示羊駝國王或他的子民有所活動(羊駝國王選擇一個區間算一次,某區間裏的人增加和諧值算一次)的總次數。code

接下來的M行,每行第一個是一個數K,K是1或2,若K=1,接下來有三個數L,R,C,表示區間[L,R]的全部人增長C的和諧值;若K=2,接下來有兩個數L,R,表示國王選擇了區間[L,R]。blog

輸出格式

每次對於國王選擇區間,輸出選擇區間裏的最大和諧值。io

樣例1

樣例輸入1

5
1
2
3
4
5
3
2 1 4
1 1 3 3
2 3 5

樣例輸出1

4
6

限制

每一個測試點1s。class

提示

保證全部的數以及結果都在longint範圍內。di

來源

經典問題改編。時間

思路

。。。帶標記下放的區間最大值,而後sb的我交了,,,4邊QUQco

代碼實現

 1 #include<cstdio>
 2 #define LL long long
 3 const int maxn=1e5+10;
 4 inline LL min_(LL x,LL y){return x<y?x:y;}
 5 inline LL max_(LL x,LL y){return x>y?x:y;}
 6 int n,m;
 7 LL t[maxn<<2],f[maxn<<2];
 8 void build(int k,int l,int r){
 9     if(l==r){
10         scanf("%lld",&t[k]);
11         return;
12     }
13     int mid=l+r>>1,ls=k<<1,rs=ls|1;
14     build(ls,l,mid);
15     build(rs,mid+1,r);
16     t[k]=max_(t[ls],t[rs]);
17 }
18 void f_down(int k,int ls,int rs){
19     t[ls]+=f[k],f[ls]+=f[k];
20     t[rs]+=f[k],f[rs]+=f[k];
21     f[k]=0;
22 }
23 void add(int k,int l,int r,int al,int ar,LL p){
24     if(al <= l && r <= ar){
25         t[k]+=p,f[k]+=p;
26         return;
27     }
28     int mid=l+r>>1,ls=k<<1,rs=ls|1;
29     if(f[k]) f_down(k,ls,rs);
30     if(al<=mid) add(ls,l,mid,al,min_(ar,mid),p);
31     if(ar>mid) add(rs,mid+1,r,max_(al,mid+1),ar,p);
32     t[k]=max_(t[ls],t[rs]);
33 }
34 #define INF 8e18
35 LL big(int k,int l,int r,int al,int ar){
36     if(l==al&&r==ar) return t[k];
37     int mid=l+r>>1,ls=k<<1,rs=ls|1;
38     if(f[k]) f_down(k,ls,rs);
39     LL ret=-INF;
40     if(al<=mid) ret=max_(ret,big(ls,l,mid,al,min_(ar,mid)));
41     if(ar>mid) ret=max_(ret,big(rs,mid+1,r,max_(al,mid+1),ar));
42     return ret;
43 }
44 int main(){
45     scanf("%d",&n);
46     build(1,1,n);
47     scanf("%d",&m);
48     LL c;
49     int k,l,r;
50     for(int i=1;i<=m;i++){
51         scanf("%d",&k);
52         if(k==1){
53             scanf("%d%d%lld",&l,&r,&c);
54             add(1,1,n,l,r,c);
55         }
56         if(k==2){
57             scanf("%d%d",&l,&r);
58             printf("%lld\n",big(1,1,n,l,r));
59         }
60     }
61     return 0;
62 }
相關文章
相關標籤/搜索