HDU - 5306 - Gorgeous Sequence - 模板 - 势能线段树(吉司机线段树)
吉司机线段树用于维护区间[l,r]对x取最小值,区间查询最小值和区间求和.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
struct node{
int l,r;
ll mx;
ll se;
int cnt;
ll sum;
};
ll arr[N];
node tr[N<<2];
void pushdown(int rt){
if(tr[rt<<1].mx > tr[rt].mx){
tr[rt<<1].sum -= (tr[rt<<1].mx-tr[rt].mx)*tr[rt<<1].cnt; //左儿子的最大值小于父结点的最大值,就把左儿子的最大值替换为父结点的最大值
tr[rt<<1].mx = tr[rt].mx;
}
if(tr[rt<<1|1].mx > tr[rt].mx){
tr[rt<<1|1].sum -= (tr[rt<<1|1].mx-tr[rt].mx)*tr[rt<<1|1].cnt;
tr[rt<<1|1].mx = tr[rt].mx;
}
}
void pushup(int rt){
tr[rt].sum = tr[rt<<1].sum + tr[rt<<1|1].sum;
tr[rt].mx = max(tr[rt<<1].mx,tr[rt<<1|1].mx);
tr[rt].cnt = 0;
if(tr[rt<<1].mx == tr[rt<<1|1].mx){
tr[rt].cnt = tr[rt<<1].cnt + tr[rt<<1|1].cnt;
tr[rt].se = max(tr[rt<<1].se,tr[rt<<1|1].se);
}else{
if(tr[rt<<1].mx > tr[rt<<1|1].mx){
tr[rt].cnt = tr[rt<<1].cnt;
tr[rt].se = max(tr[rt<<1].se,tr[rt<<1|1].mx);
}else{
tr[rt].cnt = tr[rt<<1|1].cnt;
tr[rt].se = max(tr[rt<<1].mx,tr[rt<<1|1].se);
}
}
}
void build(int rt,int l,int r){
if(l==r){
tr[rt]={l,r,arr[l],-1,1,arr[l]};
}else{
int mid=l+r>>1;
tr[rt]={l,r};
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
}
void modify(int rt,int l,int r,int x){
if(tr[rt].mx <= x){
return;
}
if(l <= tr[rt].l && r >= tr[rt].r && tr[rt].se < x){
tr[rt].sum -= (tr[rt].mx - x)*tr[rt].cnt;
tr[rt].mx = x;
return;
}
pushdown(rt);
int mid = tr[rt].l + tr[rt].r >> 1;
if(l <= mid){
modify(rt<<1,l,r,x);
}
if(r > mid){
modify(rt<<1|1,l,r,x);
}
pushup(rt);
}
ll query_max(int rt,int l,int r){
if(l <= tr[rt].l && r >= tr[rt].r){
return tr[rt].mx;
}else{
pushdown(rt);
int mid =tr[rt].l+tr[rt].r >>1;
ll res = 0;
if(l <= mid) res = query_max(rt<<1,l,r);
if(r > mid) res = max(res,query_max(rt<<1|1,l,r));
return res;
}
}
ll query_sum(int rt,int l,int r){
if(l <= tr[rt].l && r >= tr[rt].r){
return tr[rt].sum;
}else{
pushdown(rt);
int mid = tr[rt].l+tr[rt].r >>1;
ll res =0;
if(l <= mid) res += query_sum(rt<<1,l,r);
if(r > mid) res += query_sum(rt<<1|1,l,r);
return res;
}
}
int main(){
int t,n,q,cmd,x,y,v;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&q);
for(int i = 1; i <= n; i++){
scanf("%lld",&arr[i]);
}
build(1,1,n);
while(q--){
scanf("%d",&cmd);
switch (cmd){
case 0:
scanf("%d%d%d",&x,&y,&v);
modify(1,x,y,v);
break;
case 1:
scanf("%d%d",&x,&y);
printf("%d\n",query_max(1,x,y));
break;
default:
scanf("%d%d%",&x,&y);
printf("%lld\n",query_sum(1,x,y));
}
}
}
system("pause");
return 0;
}
---- suffer now and live the rest of your life as a champion ----