题目要求是在 线段树模板 那道题上同时有最小值查询和总和查询 我只够时间跑完小数据点,自己没发现哪错了
#include<bits/stdc++.h>
using namespace std;
const int XY=200005;
long long N,Q;
long long a[XY],tree_sum[XY*4],tree_min[XY*4],lazy[XY];
long long ans,A,B,C;
char c;
void build_min(long long s,long long l,long long r){
if(l==r){
tree_min[s]=a[l];
return ;
}
long long mid=(l+r)>>1;
build_min(s*2,l,mid);
build_min(s*2+1,mid+1,r);
tree_min[s]=min(tree_min[s*2],tree_min[s*2+1]);
}
void build_sum(long long s,long long l,long long r){
if(l==r){
tree_sum[s]=a[l];
return ;
}
long long mid=(l+r)>>1;
build_sum(s*2,l,mid);
build_sum(s*2+1,mid+1,r);
tree_sum[s]=tree_sum[s*2]+tree_sum[s*2+1];
}
void down(long long s){
lazy[s*2]=lazy[s];
lazy[s*2+1]=lazy[s];
lazy[s]=0;
}
void up(long long s){
tree_sum[s]=tree_sum[s*2]+tree_sum[s*2+1];
tree_min[s]=min(tree_sum[s*2],tree_sum[s*2+1]);
}
void P(long long ll,long long rr,long long s,long long l,long long r,long long k){
if(ll<=l and rr>=r){
lazy[s]+=k;
tree_sum[s]+=(r-l+1)*k;
tree_min[s]+=k;
return ;
}
down(s);
long long mid=(l+r)/2;
if(ll<=mid)P(ll,rr,s*2,l,mid,k);
if(rr>mid)P(ll,rr,s*2+1,mid+1,r,k);
up(s);
}
long long M(long long ll,long long rr,long long s,long long l,long long r){
if(ll<=l and rr>=r){
return tree_min[s];
}
down(s);
long long mid=(l+r)/2,a,b;
a=200000000;
b=200000000;
if(ll<=mid)a=M(ll,rr,s*2,l,mid);
if(rr>mid)b=M(ll,rr,s*2+1,mid+1,r);
return min(a,b);
}
long long S(long long ll,long long rr,long long s,long long l,long long r){
if(ll<=l and rr>=r){
return tree_sum[s];
}
down(s);
long long mid=(l+r)/2,a=0,b=0;
if(ll<=mid)a=S(ll,rr,s*2,l,mid);
if(rr>mid)b=S(ll,rr,s*2+1,mid+1,r);
return a+b;
}
int main(){
scanf("%lld%lld",&N,&Q);
for(long long i=1;i<=N;i++)
scanf("%lld",&a[i]);
build_min(1,1,N);
build_sum(1,1,N);
for(long long l=1;l<=Q;l++){
scanf("%s%lld%lld",&c,&A,&B);
if(c=='P'){
scanf("%lld",&C);
P(A,B,1,1,N,C);
}
else if(c=='M'){
printf("%lld\n",M(A,B,1,1,N));
}
else if(c=='S'){
printf("%lld\n",S(A,B,1,1,N));
}
}
return 0;
}