http://acm.hdu.edu.cn/showproblem.php?pid=5306
和hysbz4355一样 维护最大最小值来剪枝
#include <bits/stdc++.h>
using namespace std;
#define N 0x3f3f3f3f3f3f3f3f
#define ll long long
struct node
{
int l;
int r;
ll sum;
ll maxx;
ll cnt;
ll cmaxx;
ll laz;
};
node tree[4000010];
int n,q;
void change(ll val,int cur)
{
if(val<tree[cur].maxx)
{
tree[cur].sum-=(tree[cur].maxx-val)*tree[cur].cnt;
tree[cur].maxx=val;
tree[cur].laz=val;
}
}
void pushup(int cur)
{
tree[cur].sum=tree[2*cur].sum+tree[2*cur+1].sum;
tree[cur].maxx=max(tree[2*cur].maxx,tree[2*cur+1].maxx);
tree[cur].cnt=0;
if(tree[cur].maxx==tree[2*cur].maxx) tree[cur].cnt+=tree[2*cur].cnt;
if(tree[cur].maxx==tree[2*cur+1].maxx) tree[cur].cnt+=tree[2*cur+1].cnt;
tree[cur].cmaxx=0;
if(tree[cur].maxx!=tree[2*cur].maxx) tree[cur].cmaxx=max(tree[cur].cmaxx,tree[2*cur].maxx);
if(tree[cur].maxx!=tree[2*cur+1].maxx) tree[cur].cmaxx=max(tree[cur].cmaxx,tree[2*cur+1].maxx);
tree[cur].cmaxx=max(tree[cur].cmaxx,max(tree[2*cur].cmaxx,tree[2*cur+1].cmaxx));
}
void pushdown(int cur)
{
if(tree[cur].laz!=N)
{
change(tree[cur].laz,2*cur);
change(tree[cur].laz,2*cur+1);
tree[cur].laz=N;
return;
}
}
void build(int l,int r,int cur)
{
int m;
tree[cur].l=l;
tree[cur].r=r;
tree[cur].sum=0;
tree[cur].maxx=-N;
tree[cur].cnt=0;
tree[cur].cmaxx=-N;
tree[cur].laz=N;
if(l==r)
{
scanf("%lld",&tree[cur].sum);
tree[cur].maxx=tree[cur].sum;
tree[cur].cnt=1;
return;
}
m=(l+r)/2;
build(l,m,2*cur);
build(m+1,r,2*cur+1);
pushup(cur);
return;
}
void update(int pl,int pr,ll val,int cur)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
if(val>=tree[cur].maxx) return;
//printf("*%d %d %lld %lld*\n",tree[cur].l,tree[cur].r,tree[cur].maxx,tree[cur].cmaxx);
if(tree[cur].cmaxx<val)
{
change(val,cur);
return;
}
}
if(tree[cur].l==tree[cur].r) return;
pushdown(cur);
if(pl<=tree[2*cur].r) update(pl,pr,val,2*cur);
if(pr>=tree[2*cur+1].l) update(pl,pr,val,2*cur+1);
pushup(cur);
}
ll queryI(int pl,int pr,int cur)
{
ll res;
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
return tree[cur].maxx;
}
pushdown(cur);
res=0;
if(pl<=tree[2*cur].r) res=max(res,queryI(pl,pr,2*cur));
if(pr>=tree[2*cur+1].l) res=max(res,queryI(pl,pr,2*cur+1));
return res;
}
ll queryII(int pl,int pr,int cur)
{
ll res;
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
return tree[cur].sum;
}
pushdown(cur);
res=0;
if(pl<=tree[2*cur].r) res+=queryII(pl,pr,2*cur);
if(pr>=tree[2*cur+1].l) res+=queryII(pl,pr,2*cur+1);
return res;
}
int main()
{
ll val;
int t,op,l,r;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
build(1,n,1);
while(q--)
{
scanf("%d",&op);
if(op==0)
{
scanf("%d%d%lld",&l,&r,&val);
update(l,r,val,1);
}
else if(op==1)
{
scanf("%d%d",&l,&r);
printf("%lld\n",queryI(l,r,1));
}
else
{
scanf("%d%d",&l,&r);
printf("%lld\n",queryII(l,r,1));
}
}
}
return 0;
}
/*
100
5 5
1 2 3 4 5
0 1 3 0
1 1 4
1 3 5
2 1 5
*/