http://acm.hdu.edu.cn/showproblem.php?pid=5306
题意:
1.区间 [l,r] 对 x 取 min
2.区间查询最大值
3.区间查询和
分析:
线段树区间更新查找,查找比较容易,就是按照模板,更新需要进行查找需要更新的点,进行标记,然后通过需要更新点的个数来求和
代码:
#include<bits/stdc++.h>
using namespace std;
long long a[1000010];
#define mod 1000000007
long long Sum,Maxn;
struct node
{
long long lazy,cnt,maxn,l,r;
long long sum;
}v[1000010<<2];
void update(int k,long long val)
{
if(v[k].lazy!=0&&v[k].lazy<=val)return;
v[k].lazy=val;
if(v[k].cnt!=v[k].r-v[k].l+1)
{
v[k].maxn=val;
v[k].sum+=(v[k].r-v[k].l+1-v[k].cnt)*val;
v[k].cnt=v[k].r-v[k].l+1;
}
}
void pushUp(int k)
{
v[k].maxn=max(v[k<<1].maxn,v[(k<<1)+1].maxn);
v[k].sum=v[k<<1].sum+v[(k<<1)+1].sum;
v[k].cnt=v[k<<1].cnt+v[(k<<1)+1].cnt;
}
void dfs(int k,long long val)
{
if(v[k].maxn<=val)return;
v[k].lazy=0;
if(v[k].l==v[k].r)
{
v[k].cnt=v[k].maxn=v[k].sum=0;
return;
}
dfs(k<<1,val);
dfs((k<<1)+1,val);
pushUp(k);
}
void pushDown(int k)
{
if(v[k].lazy==0)return;
update(k<<1,v[k].lazy);
update((k<<1)+1,v[k].lazy);
v[k].lazy=0;
}
void build(int k,long long l,long long r)
{
v[k].l=l;
v[k].r=r;
v[k].lazy=0;
if(l==r)
{
v[k].sum=v[k].maxn=v[k].lazy=a[l];
v[k].cnt=1;
return;
}
long long mid;
mid=(l+r)>>1;
build(k<<1,l,mid);
build((k<<1)+1,mid+1,r);
pushUp(k);
}
void gai(int k,long long ll,long long rr,long long val)
{
if(v[k].maxn<=val)return;
if(v[k].l>=ll&&v[k].r<=rr)
{
dfs(k,val);
update(k,val);
return;
}
pushDown(k);
long long mid;
mid=(v[k].l+v[k].r)>>1;
if(mid>=ll)
gai(k<<1,ll,rr,val);
if(mid<rr)
gai((k<<1)+1,ll,rr,val);
pushUp(k);
}
void get(int k,long long ll,long long rr)
{
if(v[k].l>=ll&&v[k].r<=rr)
{
Sum+=v[k].sum;
Maxn=max(Maxn,v[k].maxn);
return;
}
long long mid;
mid=(v[k].l+v[k].r)>>1;
pushDown(k);
if(mid>=ll)
get(k<<1,ll,rr);
if(mid<rr)
get((k<<1)+1,ll,rr);
pushUp(k);
}
int main()
{
long long t,i,j,n,m,x,aa,bb,cc;
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
for(i=0;i<m;i++)
{
scanf("%lld",&x);
if(x==0)
{
scanf("%lld%lld%lld",&aa,&bb,&cc);
gai(1,aa,bb,cc);
}
else
if(x==1)
{
scanf("%lld%lld",&aa,&bb);
Maxn=0;
get(1,aa,bb);
printf("%lld\n",Maxn);
}
else
{
scanf("%lld%lld",&aa,&bb);
Sum=0;
get(1,aa,bb);
printf("%lld\n",Sum);
}
}
}
}