您的位置:首页 > 其它

hdu 5306 区间取min和询问区间和及最大数

2016-05-29 11:33 176 查看

题目链接

hdu 5306

题目描述

Problem Description

There is a sequence a of length n. We use ai to denote the i-th element in this sequence. You should do the following three types of operations to this sequence.

0 x y t: For every x≤i≤y, we use min(ai,t) to replace the original ai’s value.

1 x y: Print the maximum value of ai that x≤i≤y.

2 x y: Print the sum of ai that x≤i≤y.

Input

The first line of the input is a single integer T, indicating the number of testcases.

The first line contains two integers n and m denoting the length of the sequence and the number of operations.

The second line contains n separated integers a1,…,an (∀1≤i≤n,0≤ai<231).

Each of the following m lines represents one operation (1≤x≤y≤n,0≤t<231).

It is guaranteed that T=100, ∑n≤1000000, ∑m≤1000000.

Output

For every operation of type 1 or 2, print one line containing the answer to the corresponding query.

Sample Input

1

5 5

1 2 3 4 5

1 1 5

2 1 5

0 3 5 3

1 1 5

2 1 5

Sample Output

5

15

3

12

题解

吉如一的集训队论文讲得很清楚。存个模板。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

const int N=1000010;
struct node{
int mx,mx1,l,r,cnt;
long long sum;
void sol(int x){
if(x>=mx) return;
sum-=(mx-x)*1ll*cnt;
mx=x;
}
}t[N*4];
int a
,op,x,y,z,n,m,T;

void push_up(int k){
t[k].cnt=0;
t[k].sum=t[k*2].sum+t[k*2+1].sum;
t[k].mx=max(t[k*2].mx,t[k*2+1].mx);
t[k].mx1=max(t[k*2].mx1,t[k*2+1].mx1);
if(t[k*2].mx==t[k].mx) t[k].cnt+=t[k*2].cnt;
else t[k].mx1=max(t[k].mx1,t[k*2].mx);
if(t[k*2+1].mx==t[k].mx) t[k].cnt+=t[k*2+1].cnt;
else t[k].mx1=max(t[k].mx1,t[k*2+1].mx);
}
void push_down(int k){
t[k*2].sol(t[k].mx);
t[k*2+1].sol(t[k].mx);
}
void built(int k,int l,int r){
t[k].l=l; t[k].r=r;
if(l==r){
t[k].mx=t[k].sum=a[l];
t[k].mx1=-1; t[k].cnt=1;
return;
}
int mid=(l+r)>>1;
built(k*2,l,mid);
built(k*2+1,mid+1,r);
push_up(k);
}
void modify(int k,int l,int r,int x){
if(t[k].mx<=x) return;
if(t[k].l==l&&t[k].r==r&&t[k].mx1<x){
t[k].sol(x);
return;
}
push_down(k);
int mid=(t[k].l+t[k].r)>>1;
if(l<=mid) modify(k*2,l,min(r,mid),x);
if(r>mid) modify(k*2+1,max(l,mid+1),r,x);
push_up(k);
}
int getmax(int k,int l,int r){
if(t[k].l==l&&t[k].r==r) return t[k].mx;
push_down(k);
int mid=(t[k].l+t[k].r)>>1;
if(r<=mid) return getmax(k*2,l,r);
else if(l>mid) return getmax(k*2+1,l,r);
return max(getmax(k*2,l,mid),getmax(k*2+1,mid+1,r));
}
long long getsum(int k,int l,int r){
if(t[k].l==l&&t[k].r==r) return t[k].sum;
push_down(k);
int mid=(t[k].l+t[k].r)>>1;
if(r<=mid) return getsum(k*2,l,r);
else if(l>mid) return getsum(k*2+1,l,r);
return getsum(k*2,l,mid)+getsum(k*2+1,mid+1,r);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",a+i);
built(1,1,n);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&op,&x,&y);
if(op==0) {
scanf("%d",&z);
modify(1,x,y,z);
}
else if(op==1) printf("%d\n",getmax(1,x,y));
else printf("%lld\n",getsum(1,x,y));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: