今天早上找了一道比较综合的线段树(http://codevs.cn/problem/4927/),虽然题目很水,但是作为一名蒟蒻,我码了半个上午才码出来,接着“静态查错”调了一个下午(捂脸),wa了十几发。晚上拍了一会儿终于调了出来……
//codevs 4927 线段树加强
#include <cstdio>
#include <algorithm>
#define maxn (100000+5)
#define LL long long
using namespace std;
struct xx{
LL sum,min,max,set,add;
}a[maxn*3];
LL n,Q,x,y1,y2,v;
char ch;
inline LL get_num(){
ch=getchar();
LL num=0,flag=1;
while(ch<'0'||ch>'9'){if(ch=='-')flag=-1;ch=getchar(); }
while(ch>='0'&&ch<='9'){num=(num<<3)+(num<<1)+ch-'0';ch=getchar(); }
return flag*num;
}
void maintain(LL t,LL l,LL r)
{
/*a[t].max=0x7f3f3f3f3f,
a[t].min=-0x7f3f3f3f3f,
a[t].sum=0;
*/
LL lc=t<<1,rc=(t<<1)+1;
if (r>l)
{
a[t].max=max(a[lc].max,a[rc].max);
a[t].min=min(a[lc].min,a[rc].min);
a[t].sum=a[lc].sum+a[rc].sum;
}
}
void pushdown(LL t,LL l,LL r)
{
LL lc=t<<1,rc=(t<<1)+1,m=l+((r-l)>>1);
if (a[t].set>=0)
{
a[lc].max=a[rc].max=a[lc].min=a[rc].min=a[lc].set=a[rc].set=a[t].set;
a[lc].sum=(m-l+1)*a[t].set;
a[rc].sum=(r-m) *a[t].set;
a[t].set=-1;
a[lc].add=a[rc].add=a[t].add=0;
}
if (a[t].add) {
if (a[lc].set==-1) a[lc].add+=a[t].add;else a[lc].set+=a[t].add;
if (a[rc].set==-1) a[rc].add+=a[t].add;else a[rc].set+=a[t].add;
a[lc].min+=a[t].add,a[rc].min+=a[t].add,
a[lc].max+=a[t].add,a[rc].max+=a[t].add,
a[lc].sum+=(m-l+1)*a[t].add,
a[rc].sum+=(r-m) *a[t].add,
a[t].add=0;
}
}
void build(LL t,LL l,LL r)
{
if (l==r)
{
scanf("%lld",&x),a[t]=(xx){x,x,x,-1,0};
return ;
}
LL m=l+((r-l)>>1),lc=t<<1,rc=(t<<1)+1;
build(lc,l,m);
build(rc,m+1,r);
a[t].set=-1;
maintain(t,l,r);
return ;
}
void update_add(LL t,LL l,LL r)
{
LL lc=t<<1,rc=(t<<1)+1;
if (y1<=l&&r<=y2) {
a[t].max+=v;
a[t].min+=v;
a[t].sum+=(r-l+1)*v;
if (a[t].set>=0)
{
a[t].set+=v;return ;
}
a[t].add+=v;
}
else {
LL m=l+((r-l)>>1);
pushdown(t,l,r);
if (y1<=m) update_add(lc,l,m);
if (y2>m) update_add(rc,m+1,r);
maintain(t,l,r);
}
}
void update_num(LL t,LL l,LL r)
{
LL lc=t<<1,rc=(t<<1)+1;
if (y1<=l&&r<=y2)
a[t].min=a[t].max=a[t].set=v,
a[t].sum=(r-l+1)*v,a[t].add=0;
else{
pushdown(t,l,r);
LL m=l+((r-l)>>1);
if (y1<=m) update_num(lc,l,m);
if (y2>m) update_num(rc,m+1,r);
maintain(t,l,r);
}
}
LL query(LL t,LL l,LL r)
{
if (y1<=l&&r<=y2) return a[t].sum;
LL m=l+((r-l)>>1),lc=t<<1,rc=(t<<1)+1,ans=0;
pushdown(t,l,r);
if (y1<=m) ans+=query(lc,l,m);
if (y2>m) ans+=query(rc,m+1,r);
maintain(t,l,r);
return ans;
}
LL max_query(LL t,LL l,LL r)
{
if (y1<=l&&r<=y2) return a[t].max;
LL m=l+((r-l)>>1),lc=t<<1,rc=(t<<1)+1,ans=-0x7f3f3f3f;
pushdown(t,l,r);
if (y1<=m) ans=max(ans,max_query(lc,l,m));
if (y2>m) ans=max(ans,max_query(rc,m+1,r));
maintain(t,l,r);
return ans;
}
LL min_query(LL t,LL l,LL r)
{
if (y1<=l&&r<=y2) return a[t].min;
LL m=l+((r-l)>>1),lc=t<<1,rc=(t<<1)+1,ans=0x7f3f3f3f;
pushdown(t,l,r);
if (y1<=m) ans=min(ans,min_query(lc,l,m));
if (y2>m) ans=min(ans,min_query(rc,m+1,r));
maintain(t,l,r);
return ans;
}
void work(){
LL b,c,d;
char s[10];
for(LL i=1;i<=Q;i++){
scanf("%s",&s);
y1=get_num();y2=get_num();
if(s[0]=='a'){
v=get_num();
update_add(1,1,n);continue;
}
if(s[1]=='e'){
v=get_num();
update_num(1,1,n);continue;
}
if(s[1]=='u'){
printf("%lld\n",query(1,1,n));continue;
}
if(s[1]=='a'){
printf("%lld\n",max_query(1,1,n));continue;
}
if(s[1]=='i'){
printf("%lld\n",min_query(1,1,n));
}
}
}
int main()
{
freopen("data.out","r",stdin);
freopen("wa.out","w",stdout);
n=get_num();Q=get_num();
build(1,1,n);
work();
return 0;
}