There is a sequence x≤i≤y.
InputThe first line of the input is a single integer 2, print one line containing the answer to the corresponding query.
Sample Input
1 5 5 1 2 3 4 5 1 1 5 2 1 5 0 3 5 3 1 1 5 2 1 5
Sample Output
5 15 3 12
题意:三种操作,0区间min操作;1区间求max;2区间求和。
思路:segments tres beats模板题。 因为都是区间操作,所以有很多相同的值,我们记录每个区间的最大值,最大值的数量,以及第二大值。然后就可以搞了,不用lazy,下推的时候如果mx[Now]比儿子还小,那么久自然的下推即可。
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1000010; int mx[maxn<<2],mc[maxn<<2],se[maxn<<2]; ll sum[maxn<<2]; void pushdown(int Now) { if(mx[Now]<mx[Now<<1]){ sum[Now<<1]-=(ll)(mx[Now<<1]-mx[Now])*mc[Now<<1]; mx[Now<<1]=mx[Now]; } if(mx[Now]<mx[Now<<1|1]){ sum[Now<<1|1]-=(ll)(mx[Now<<1|1]-mx[Now])*mc[Now<<1|1]; mx[Now<<1|1]=mx[Now]; } } void pushup(int Now) { sum[Now]=sum[Now<<1]+sum[Now<<1|1]; mx[Now]=max(mx[Now<<1],mx[Now<<1|1]); if(mx[Now<<1]==mx[Now<<1|1]){ mc[Now]=mc[Now<<1]+mc[Now<<1|1]; se[Now]=max(se[Now<<1],se[Now<<1|1]); } else { if(mx[Now<<1]>mx[Now<<1|1]){ mc[Now]=mc[Now<<1]; se[Now]=max(mx[Now<<1|1],se[Now<<1]); } else { mc[Now]=mc[Now<<1|1]; se[Now]=max(mx[Now<<1],se[Now<<1|1]); } } } void build(int Now,int L,int R) { if(L==R){ scanf("%d",&mx[Now]); sum[Now]=mx[Now]; se[Now]=0; mc[Now]=1; return ; } int Mid=(L+R)>>1; build(Now<<1,L,Mid); build(Now<<1|1,Mid+1,R); pushup(Now); } ll querysum(int Now,int L,int R,int l,int r){ if(l<=L&&r>=R) return sum[Now]; int Mid=(L+R)>>1; ll res=0; pushdown(Now); if(l<=Mid) res+=querysum(Now<<1,L,Mid,l,r); if(r>Mid) res+=querysum(Now<<1|1,Mid+1,R,l,r); return res; } int querymax(int Now,int L,int R,int l,int r){ if(l<=L&&r>=R) return mx[Now]; int Mid=(L+R)>>1,res=-1; pushdown(Now); if(l<=Mid) res=max(res,querymax(Now<<1,L,Mid,l,r)); if(r>Mid) res=max(res,querymax(Now<<1|1,Mid+1,R,l,r)); return res; } void update(int Now,int L,int R,int l,int r,int x) { if(mx[Now]<=x) return ; if(l<=L&&r>=R){ if(se[Now]<x){ sum[Now]-=(ll)mc[Now]*(mx[Now]-x); mx[Now]=x; return ; } } int Mid=(L+R)>>1; pushdown(Now); if(l<=Mid) update(Now<<1,L,Mid,l,r,x); if(r>Mid) update(Now<<1|1,Mid+1,R,l,r,x); pushup(Now); } int main() { int T,N,M,L,R,opt,x; scanf("%d",&T); while(T--){ scanf("%d%d",&N,&M); build(1,1,N); while(M--){ scanf("%d%d%d",&opt,&L,&R); if(opt==1) printf("%d\n",querymax(1,1,N,L,R)); else if(opt==2) printf("%lld\n",querysum(1,1,N,L,R)); else { scanf("%d",&x); update(1,1,N,L,R,x); } } } return 0; }