MnZn 求助线段树板子题
查看原帖
MnZn 求助线段树板子题
964089
run_away楼主2024/10/20 21:50

rt,不知道为什么区间求值错了,但是每个单点又是对的(

马蜂可能有点鬼畜请见谅

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
// static char buf[100],*p1=buf,*p2=buf,obuf[100],*p3=obuf;
// #define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,100,stdin),p1==p2)?EOF:*p1++
// #define putchar(x) (p3-obuf<100)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count());
#define dbg(x) cout<<#x<<": "<<x<<"\n"
#define usetime() printf("time: %.3lfs\n",clock()*1.0/CLOCKS_PER_SEC)
inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;}
inline void write(ll x){if(!x){putchar(48);putchar('\n');return;}short top=0,s[40];if(x<0)x=-x,putchar(45);while(x)s[top++]=x%10^48,x/=10;while(top--)putchar(s[top]);putchar('\n');}
namespace tobe{
    const ll maxn=5e5+5,mod=998244353;
    ll n,q,a[maxn];
    struct node{
    	ll l,r,val,mx,mn,tag,add;
    }t[maxn<<2];
    #define ls (x<<1)
    #define rs (x<<1|1)
    #define mid ((t[x].l+t[x].r)>>1)
    inline void pushup(ll x){
    	t[x].val=t[ls].val+t[rs].val;
    	t[x].mx=max(t[ls].mx,t[rs].mx);
    	t[x].mn=min(t[ls].mn,t[rs].mn);
    }
    inline void pushdown(ll x){
    	if(t[x].tag!=-1){
    		t[ls].add=t[rs].add=0;
    		t[ls].val=(mid-t[x].l+1)*t[x].tag;
    		t[ls].mx=t[ls].mn=t[ls].tag=t[x].tag;
	    	t[rs].val=(t[x].r-mid)*t[x].tag;
	    	t[rs].mx=t[rs].mn=t[rs].tag=t[x].tag;
	    	t[x].tag=-1;
    	}
    	if(t[x].add){
    		t[ls].val+=(mid-t[x].l+1)*t[x].add;
    		t[ls].mx+=t[x].add,t[ls].mn+=t[x].add;
    		t[ls].add+=t[x].add;
	    	t[rs].val+=(t[x].r-mid)*t[x].add;
	    	t[rs].mx+=t[x].add,t[rs].mn+=t[x].add;
	    	t[rs].add+=t[x].add;
	    	t[x].add=0;
    	}
    }
    inline void build(ll x,ll l,ll r){
    	t[x].l=l,t[x].r=r,t[x].tag=-1;
    	if(l==r){
    		t[x].val=t[x].mx=t[x].mn=a[l];
    		return;
    	}
    	build(ls,l,mid),build(rs,mid+1,r);
    	pushup(x);
    }
    inline void update(ll x,ll l,ll r,ll k){
    	if(l<=t[x].l&&t[x].r<=r){
    		t[x].add=0;
    		t[x].val=(t[x].r-t[x].l+1)*k;
    		t[x].mx=t[x].mn=t[x].tag=k;
    		return;
    	}
    	pushdown(x);
    	if(l<=mid)update(ls,l,r,k);
    	if(r>mid)update(rs,l,r,k);
    	pushup(x);
    }
    inline void div(ll x,ll l,ll r,ll k){
    	if(l<=t[x].l&&t[x].r<=r){
    		if(t[x].mx!=t[x].mn)return;
    		ll chan=t[x].mx/k-t[x].mx;
    		t[x].val+=(t[x].r-t[x].l+1)*chan;
    		t[x].mx+=chan,t[x].mn+=chan;
    		t[x].add+=chan;
    		return;
    	}
    	pushdown(x);
    	if(l<=mid)div(ls,l,r,k);
    	if(r>mid)div(rs,l,r,k);
    	pushup(x);
    }
    inline ll query(ll x,ll l,ll r){
    	if(l<=t[x].l&&t[x].r<=r)return t[x].val;
    	pushdown(x);ll res=0;
    	if(l<=mid)res+=query(ls,l,r);
    	if(r>mid)res+=query(rs,l,r);
    	return res;
    }
    inline void mian(){
        n=read(),q=read();
        for(ll i=1;i<=n;++i)a[i]=read();
        build(1,1,n);
        while(q--){
        	ll op=read(),l=read(),r=read();
        	if(op==1){
        		ll k=read();div(1,l,r,k);
        	}
        	else if(op==2){
        		ll k=read();update(1,l,r,k);
        	}
        	else write(query(1,l,r));
        }
    }
}
signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ll t=1;
    while(t--)tobe::mian();
    // fwrite(obuf,p3-obuf,1,stdout);
    return 0;
}
2024/10/20 21:50
加载中...