线段树30pts求调
查看原帖
线段树30pts求调
569236
yf0207楼主2022/10/13 19:37
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1000010;
int p[N],n,m,mod;
struct node
{
    int l,r,sum,lazyadd,lazymul;
}a[N];
void update(int k)
{
    if(a[k].l==a[k].r)return;
    a[k].sum=(a[k*2].sum+a[k*2+1].sum)%mod;
    return;
}
void build(int k,int l,int r)
{
    a[k].l=l;a[k].r=r;a[k].lazymul=1;a[k].lazyadd=0;
    if(l==r)
    {
        a[k].sum=p[l]%mod;
        return;
    }
    int mid=(l+r)/2;
    build(k*2,l,mid);
    build(k*2+1,mid+1,r);
    update(k);
}
void down(int k)
{
    if(a[k].l==a[k].r)return;
    a[k*2].sum=(a[k].lazymul*a[k*2].sum+(a[k].lazyadd*(a[k*2].r-a[k*2].l+1))%mod)%mod;
    a[k*2+1].sum=(a[k].lazymul*a[k*2+1].sum+(a[k].lazyadd*(a[k*2+1].r-a[k*2+1].l+1))%mod)%mod;
	a[k*2].lazymul*=a[k].lazymul;a[k*2].lazymul%=mod;
	a[k*2+1].lazymul*=a[k].lazymul;a[k*2+1].lazymul%=mod;
	a[k*2].lazyadd*=a[k].lazymul;a[k*2].lazyadd+=a[k].lazyadd;a[k*2].lazymul%=mod;
	a[k*2+1].lazyadd*=a[k].lazymul;a[k*2+1].lazyadd+=a[k].lazyadd;a[k*2+1].lazymul%=mod;
	a[k].lazymul=1;
	a[k].lazyadd=0;
	update(k);
}
void add(int k,int l,int r,int x)
{
    if(l>r)return;
	if(a[k].l>=l&&a[k].r<=r)
	{
		a[k].sum+=(a[k].r-a[k].l+1)*x;a[k].sum%=mod;
		a[k].lazyadd+=x;a[k].lazyadd%=mod;
		return;
	}
	down(k);
	int mid=(a[k].l+a[k].r)/2;
	if(r>mid) add(k*2+1,l,r,x);
    if(l<=mid) add(k*2,l,r,x);
	update(k);
}
void mul(int k,int l,int r,int x)
{
    if(l>r)return;
	if(a[k].l>=l&&a[k].r<=r)
	{
		a[k].sum*=x;a[k].sum%=mod;
		a[k].lazymul*=x;a[k].lazymul%=mod;
		a[k].lazyadd*=x;a[k].lazyadd%=mod;
		return;
	}
	down(k);
	int mid=(a[k].l+a[k].r)/2;
	if(r>mid) mul(k*2+1,l,r,x);
    if(l<=mid) mul(k*2,l,r,x);
	update(k);
}
int query(int k,int l,int r)
{
    if(a[k].l>=l&&a[k].r<=r)return a[k].sum;
	down(k);
	int mid=(a[k].l+a[k].r)/2,ret=0;
	if(l<=mid){ret+=query(k*2,l,r);ret%=mod;}
	if(r>mid){ret+=query(k*2+1,l,r);ret%=mod;}
	return ret;
}
signed main()
{
    scanf("%lld%lld%lld",&n,&m,&mod);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&p[i]);
        p[i]%=mod;
    }
    build(1,1,n);
    while(m--)
    {
        int opt,x,y,k;
        scanf("%lld",&opt);
        if(opt==1)
        {
            scanf("%lld%lld%lld",&x,&y,&k);
            mul(1,x,y,k);
        }
        if(opt==2)
        {
            scanf("%lld%lld%lld",&x,&y,&k);
            add(1,x,y,k);
        }
        if(opt==3)
        {
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",query(1,x,y));
        }
    }
    return 0;
}
2022/10/13 19:37
加载中...