题目链接:hdu 5306 Gorgeous Sequence
题意:
给你一个序列,有三种操作。
0 x y t:将[x,y]的数取min(a[i],t)
1 x y:求[x,y]的最大值
2 x y:求[x,y]的区间和
题解:
吉老师的课件题:传送门
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 #define ls l,m,rt<<1 4 #define rs m+1,r,rt<<1|1 5 using namespace std; 6 typedef long long ll; 7 const int N=4e6+7; 8 9 int t,n,m,mx[N],se[N],num[N]; 10 ll sum[N]; 11 12 inline void dec_tag(int rt,int val) 13 { 14 if(val>=mx[rt])return; 15 sum[rt]-=1ll*(mx[rt]-val)*num[rt],mx[rt]=val; 16 } 17 18 inline void PD(int rt){dec_tag(rt<<1,mx[rt]),dec_tag(rt<<1|1,mx[rt]);} 19 20 inline void PU(int rt) 21 { 22 int l=rt<<1,r=rt<<1|1; 23 sum[rt]=sum[l]+sum[r],num[rt]=0; 24 mx[rt]=max(mx[l],mx[r]); 25 se[rt]=max(max(se[l],se[r]),mx[l]==mx[r]?0:min(mx[l],mx[r])); 26 if(mx[rt]==mx[l])num[rt]+=num[l]; 27 if(mx[rt]==mx[r])num[rt]+=num[r]; 28 } 29 30 void build(int l=1,int r=n,int rt=1) 31 { 32 se[rt]=-1; 33 if(l==r) 34 { 35 int x; 36 scanf("%d",&x); 37 sum[rt]=mx[rt]=x,num[rt]=1; 38 return; 39 } 40 int m=l+r>>1; 41 build(ls),build(rs); 42 PU(rt); 43 } 44 45 void update(int L,int R,int val,int l=1,int r=n,int rt=1) 46 { 47 if(val>=mx[rt])return; 48 if(L<=l&&r<=R&&val>se[rt]){dec_tag(rt,val);return;} 49 PD(rt); 50 int m=l+r>>1; 51 if(L<=m)update(L,R,val,ls); 52 if(R>m)update(L,R,val,rs); 53 PU(rt); 54 } 55 56 ll query(int type,int L,int R,int l=1,int r=n,int rt=1) 57 { 58 if(L<=l&&r<=R){return type==1?mx[rt]:sum[rt];} 59 PD(rt); 60 int m=l+r>>1;ll ans=0; 61 if(L<=m)ans=(type==1?max(ans,query(type,L,R,ls)):ans+query(type,L,R,ls)); 62 if(R>m)ans=(type==1?max(ans,query(type,L,R,rs)):ans+query(type,L,R,rs)); 63 return ans; 64 } 65 66 int main() 67 { 68 scanf("%d",&t); 69 while(t--) 70 { 71 scanf("%d%d",&n,&m); 72 build(); 73 int a,b,c,d; 74 F(i,1,m) 75 { 76 scanf("%d",&a); 77 if(!a)scanf("%d%d%d",&b,&c,&d),update(b,c,d); 78 else scanf("%d%d",&b,&c),printf("%lld\n",query(a,b,c)); 79 } 80 } 81 return 0; 82 }