社区讨论

大佬们帮忙debug一下QWQ(线段树区间乘)

学术版参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mi7y0gal
此快照首次捕获于
2025/11/21 05:28
4 个月前
此快照最后确认于
2025/11/21 05:28
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
#define ll long long
ll n,m,a[100005];
ll mo;
ll addj[N*4],addc[N<<2];
ll sum[N*4];
void build(ll k,ll l,ll r)
{
	addc[k]=1;
    if(l==r)
    {
        sum[k]=a[l];
        return;
    }
    ll mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    sum[k]=sum[k<<1]%mo+sum[k<<1|1]%mo;
    sum[k]%=mo;
}
void pushdown(ll k,ll l,ll r,ll mid)
{
    if(addj[k]==0&&addc[k]==1) return;
    ll lc=k<<1,rc=k<<1|1;
    addc[lc]=(1ll*addc[lc]*addc[k])%mo;
    addj[lc]=(1ll*addj[lc]*addc[k])%mo+addj[k];
    addc[rc]=(1ll*addc[rc]*addc[k])%mo;
    addj[rc]=(1ll*addj[rc]*addc[k])%mo+addj[k];
    addc[lc]%=mo;addc[rc]%=mo;addj[lc]%=mo;addj[rc]%=mo;
    sum[lc]=(1ll*sum[lc]*addc[k])%mo+(long long)(addj[lc]%mo)*((r-l+1)%mo);
    sum[rc]=(1ll*sum[rc]*addc[k])%mo+(long long)(addj[rc]%mo)*((r-l+1)%mo);
    sum[lc]%=mo;sum[rc]%=mo;
    addj[k]=0;addc[k]=1;
}
ll query(ll k,ll l,ll r,ll x,ll y)
{
    if(l>=x&&r<=y) return sum[k]%mo;
    ll mid=l+r>>1;
    ll res=0;
    pushdown(k,l,r,mid);
    if(x<=mid) res+=query(k<<1,l,mid,x,y);
res%=mo;
    if(mid<y) res+=query(k<<1|1,mid+1,r,x,y);
res%=mo;
    return res%mo;
}
void modify_jia(ll k,ll l,ll r,ll x,ll y,ll v)
{
    if(l>=x&&r<=y)
    {
    	addj[k]+=v;
    	addj[k]%=mo;
    	sum[k]+=(long long)(v%mo)*((r-l+1)%mo);
    	sum[k]%=mo;
    	return;
	}
    ll mid=l+r>>1;
    pushdown(k,l,r,mid);
    if(x<=mid) modify_jia(k<<1,l,mid,x,y,v);
    if(mid<y) modify_jia(k<<1|1,mid+1,r,x,y,v);
    sum[k]=sum[k<<1]%mo+sum[k<<1|1]%mo;
    sum[k]%=mo;
}
void modify_cheng(ll k,ll l,ll r,ll x,ll y,ll v)
{
    if(l>=x&&r<=y)
    {
    	addc[k]=(addc[k]*v)%mo;
    	addj[k]=(addj[k]*v)%mo;
    	sum[k]=(sum[k]*v)%mo;
    	return;
	}
    ll mid=l+r>>1;
    pushdown(k,l,r,mid);
    if(x<=mid) modify_cheng(k<<1,l,mid,x,y,v);
    if(mid<y) modify_cheng(k<<1|1,mid+1,r,x,y,v);
    sum[k]=sum[k<<1]%mo+sum[k<<1|1]%mo;
    sum[k]%=mo;
}
int main()
{
    scanf("%lld%lld%lld",&n,&m,&mo);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    ll x,y,z;
    while(m--)
    {
        ll lin;
        scanf("%lld",&lin);
        if(lin==1)
        {
            scanf("%lld%lld%lld",&x,&y,&z);
            modify_cheng(1,1,n,x,y,z);
        }
        else if(lin==2)
        {
        	scanf("%lld%lld%lld",&x,&y,&z);
            modify_jia(1,1,n,x,y,z);
		}
        else
        {
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",query(1,1,n,x,y)%mo);
        }
    }
    return 0;
}
样例都没过,但怎么看都觉得没问题
样例:
5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
(区间乘模板)

回复

1 条回复,欢迎继续交流。

正在加载回复...