MnZn 线段树 30pts 求助
查看原帖
MnZn 线段树 30pts 求助
332488
Wind_Journey楼主2022/11/12 10:48

Rt , 这个题是线段树维护区间和与区间最小值 ,我的代码打了懒标记 ,但是只有 30 pts , 其余全部 TLE ,求大佬指导。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#define int long long
#define rg register
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define in(a) a=read()
#define out(a) write(a)
#define oute(a) write(a),putchar('\n')
#define outs(a) write(a),putchar(' ')
#define INF 0x7f7f7f7f
#define LONGINF 0x7fffffffffffffff
#define endl '\n'
// #define OI_DEBUG 
// #define _IOFAST
using namespace std;
namespace OI_fast{
	inline bool isnum(char x){
		return x>='0'&&x<='9';
	}
	inline int read(){
		int x=0,w=0;
		char ch='$';
		while(!isnum(ch)){w|=ch=='-';ch=getchar();}
		while(isnum(ch)){x=x*10+(ch-'0');ch=getchar();}
		return w?-x:x;
	}
	inline void write(int x){
		if(x<0) putchar('-'),x=-x;
		if(x>9) write(x/10);
		putchar((x%10)+'0');
		return;
	}
	inline int fpow(int x,int y,int p){
		int base=x,sum=1;
		while(y){
			if(y&1) sum*=!p?base:base%p;
			base*=!p?base:base%p;
			if(p){sum%=p;base%=p;}
			y>>=1;
		} 
		return sum;
	}
	struct Reader{
		friend Reader & operator >> (Reader &reader,int &x){
			x=read();
			return reader;
		}
	} in;
	struct Writer{
		friend Writer & operator << (Writer &writer,int &x){
			write(x);
			return writer;
		}
	} out;
}
using namespace OI_fast;
const int N=200010;
struct node{
    int l,r,sum,lazy,minn;
    node() {l=r=sum=lazy=0,minn=LONGINF;}
}a[N*5];
int n,m,val[N];
inline void update(int x){
    a[x].sum=a[x*2].sum+a[x*2+1].sum;
    a[x].minn=Min(a[x*2].minn,a[x*2+1].minn);
    return;
}
inline void build(int x,int l,int r){
    a[x].l=l,a[x].r=r;
    if(l==r) {a[x].sum=a[x].minn=val[l];return;}
    int mid=(l+r)>>1;
    build(x*2,l,mid);
    build(x*2+1,mid+1,r);
    update(x);
    return;
}
inline void pushdown(int x){
    if(a[x].lazy){
        if(a[x].l==a[x].r) {a[x].lazy=0;return;}
        a[x*2].sum+=(a[x*2].r-a[x*2].l+1)*a[x].lazy;
        a[x*2+1].sum+=(a[x*2+1].r-a[x*2+1].l+1)*a[x].lazy;
        a[x*2].minn+=a[x].lazy;
        a[x*2+1].minn+=a[x].lazy;
        a[x*2].lazy+=a[x].lazy;
        a[x*2+1].lazy+=a[x].lazy;
        a[x].lazy=0;
    }
    return;
}
inline void change_segment(int x,int l,int r,int k){
    if(a[x].l>=l&&a[x].r<=r) {
        a[x].sum+=(a[x].r-a[x].l+1)*k;
        a[x].minn+=k,a[x].lazy+=k;
        return;
    }
    pushdown(x);
    int mid=(a[x].l+a[x].r)>>1;
    if(l<=mid) change_segment(x*2,l,r,k);
    if(r>mid) change_segment(x*2+1,l,r,k);
    update(x);
    return;
}
inline int query(int x,int l,int r){
    if(a[x].l>=l&&a[x].r<=r) return a[x].sum;
    pushdown(x);
    int mid=(a[x].l+a[x].r)>>1,ans=0;
    if(l<=mid) ans+=query(x*2,l,r);
    if(r>mid) ans+=query(x*2+1,l,r);
    return ans;
}
inline int segmin(int x,int l,int r){
    if(a[x].l>=l&&a[x].r<=r) return a[x].minn;
    pushdown(x);
    int mid=(a[x].l+a[x].r)>>1,ans=LONGINF;
    if(l<=mid) ans=Min(ans,segmin(x*2,l,r));
    if(r>mid) ans=Min(ans,segmin(x*2+1,l,r));
    return ans;
}
signed main(){
	#ifdef _IOFAST
	std::ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	#endif
	#ifdef OI_DEBUG
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	#endif
	in>>n>>m;
    for(int i=1;i<=n;i++) in>>val[i];
    build(1,1,n);
    for(int i=1;i<=m;i++){
        char c;int x,y;
        cin>>c>>x>>y;
        if(c=='M') oute(segmin(1,x,y));
        else if(c=='S') oute(query(1,x,y));
        else{
            int k=read();
            change_segment(1,x,y,k);
        }
    }
	return 0;
}
2022/11/12 10:48
加载中...