HDU 5306 Gorgeous Sequence
吉司机线段树。
奥妙重重。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
const int N=1e6+7;
typedef long long LL;
using namespace std;
int T,n,m,mx[N<<2],cd[N<<2],a[N],c[N];
LL sum[N<<2];
template<typename T> void read(T &x) {
T f=1; x=0; char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
void update(int x) {
mx[x]=max(mx[lc],mx[rc]);
cd[x]=max(cd[lc],cd[rc]); c[x]=0;
if(mx[lc]!=mx[rc]) cd[x]=max(cd[x],min(mx[lc],mx[rc]));
if(mx[lc]==mx[x]) c[x]+=c[lc];
if(mx[rc]==mx[x]) c[x]+=c[rc];
sum[x]=sum[lc]+sum[rc];
}
void get_min(int x,int v) {
if(mx[x]<=v) return;
sum[x]=sum[x]+(LL)(v-mx[x])*c[x]; mx[x]=v;
}
void down(int x,int l,int r) {
if(l==r) return;
get_min(lc,mx[x]);
get_min(rc,mx[x]);
}
void build(int x,int l,int r) {
if(l==r) { c[x]=1; mx[x]=sum[x]=a[l]; cd[x]=-1; return;}
build(lc,l,mid); build(rc,mid+1,r);
update(x);
}
void change(int x,int l,int r,int ql,int qr,int t) {
if(t>=mx[x]) return;
if(l>=ql&&r<=qr&&t>cd[x]) {
get_min(x,t);
return ;
}
down(x,l,r);
if(ql<=mid) change(lc,l,mid,ql,qr,t);
if(qr>mid) change(rc,mid+1,r,ql,qr,t);
update(x);
}
LL qry(int x,int l,int r,int ql,int qr,int o) {
if(l>=ql&&r<=qr) return o==1?mx[x]:sum[x];
down(x,l,r);
if(qr<=mid) return qry(lc,l,mid,ql,qr,o);
if(ql>mid) return qry(rc,mid+1,r,ql,qr,o);
if(o==1) return max(qry(lc,l,mid,ql,qr,o),qry(rc,mid+1,r,ql,qr,o));
else return qry(lc,l,mid,ql,qr,o)+qry(rc,mid+1,r,ql,qr,o);
}
int main() {
read(T);
while(T--) {
read(n); read(m);
for(int i=1;i<=n;i++) read(a[i]);
build(1,1,n);
while(m--) {
int o,x,y,t;
read(o); read(x); read(y);
if(o==0) {
read(t);
change(1,1,n,x,y,t);
}
else if(o==1) printf("%lld\n",qry(1,1,n,x,y,1));
else printf("%lld\n",qry(1,1,n,x,y,0));
}
}
return 0;
}