救救孩子
查看原帖
救救孩子
575802
Technablode楼主2022/2/13 21:26
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long ll;
const int N=2e5+10;//maximum data
const ll INF=0x3f3f3f3f3f3f3f3f;

int n,m,l,r,k;
char op;

struct node{
    int Left,Right;
    ll sum,Lazy,minx;
}tree[N*4];

inline void Merge(int x){
    tree[x].minx=min(tree[x<<1].minx,tree[x<<1|1].minx);
    tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
    return ;//update tree[root].sum & tree[root].maxx
}

inline void push_down(int root){
    ll lazy=tree[root].Lazy;
    if(lazy){
        tree[root].Lazy=0;
        tree[root<<1].Lazy+=lazy;//update Lazy
        tree[root<<1|1].Lazy+=lazy;
        tree[root<<1].minx+=lazy;
        tree[root<<1|1].minx+=lazy;//update minx
        tree[root<<1].sum+=lazy*(tree[root<<1].Right-tree[root<<1].Left+1);
        tree[root<<1|1].sum+=lazy*(tree[root<<1|1].Right-tree[root<<1|1].Left+1);//update sum
    }
    return ;
}

inline void build(int root,int left,int right){
    tree[root].Left=left;
    tree[root].Right=right;
    if(left==right){//if tree[root] is the tree's leaf
        ll x;
        scanf("%lld",&x);
        tree[root].sum=x;//input x as the initial value of tree[left].sum and tree[left].minx
        tree[root].minx=x;
        return ;
    }
    int mid=(left+right)>>1;
    build(root<<1,left,mid);
    build(root<<1|1,mid+1,right);//build leftson and rightson
    Merge(root);
}

inline void update(int root,int left,int right,int x,int y,int k){
	if(left>=x&&right<=y){
		tree[root].Lazy+=k;
		tree[root].minx+=k;
		tree[root].sum+=k*(tree[root].Right-tree[root].Left+1);
		return ;
	} 
	push_down(root);
	int mid=(left+right)>>1;
	if(left<=mid) update(root<<1,left,mid,x,y,k);
	if(right>mid) update(root<<1|1,mid+1,right,x,y,k);
	Merge(root);
	return ;
}

inline ll query_min(int root,int left,int right,int x,int y){
    if(left>=x&&right<=y) return tree[root].minx;
    push_down(root);
    int mid=(left+right)>>1;
    ll ans=INF;
    if(left<=mid) ans=min(ans,query_min(root<<1,left,mid,x,y));
    if(right>mid) ans=min(ans,query_min(root<<1|1,mid+1,right,x,y));
    return ans;
}

inline ll query(int root,int left,int right,int x,int y){
    if(left>=x&&right<=y) return tree[root].sum;
    push_down(root);
    int mid=(left+right)>>1;
    ll ans=0;
    if(left<=mid) ans+=query(root<<1,left,mid,x,y);
    if(right>mid) ans+=query(root<<1|1,mid+1,right,x,y);
    return ans;
}

int main(){
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while(m--){
        scanf("%c",&op);
        if(op=='M'){
            scanf("%d%d",&l,&r);
            printf("%lld\n",query_min(1,1,n,l,r));
        }
        else if(op=='P'){
            scanf("%d%d%d",&l,&r,&k);
            update(1,1,n,l,r,k);
        }
        else if(op=='S'){
            scanf("%d%d",&l,&r);
            printf("%lld\n",query(1,1,n,l,r));
        }
    }
    return 0;
}
2022/2/13 21:26
加载中...