线段树求调,样例都红
查看原帖
线段树求调,样例都红
551100
Hoks楼主2022/12/4 21:56
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node
{int su,mu,ad,dx;}a[400010];
int n,m,mod;
int read()
{
	char c=getchar();int x=0;
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x;
}
void build(int u,int l,int r)
{
    a[u].dx=r-l+1;
    if(l==r){a[u].su=read()%mod,a[u].mu=1;return;}
    int mid=(l+r)>>1,lu=u*2,ru=u*2+1;
    build(lu,l,mid);
    build(ru,mid+1,r);
    a[u].su=(a[lu].su+a[ru].su)%mod;
    a[u].mu=1;
}
void pushdown(int u,int l,int r)
{
    int lu=u*2,ru=u*2+1;
    if(l==r) return ;
    a[lu].su=a[lu].su*a[u].mu+a[u].ad*a[lu].dx;
    a[ru].su=a[ru].su*a[u].mu+a[u].ad*a[ru].dx;
    a[lu].su%=mod,a[ru].su%=mod;
    a[lu].ad=a[lu].ad*a[u].mu+a[u].ad;
    a[ru].ad=a[ru].ad*a[u].mu+a[u].ad;
    a[lu].ad%=mod,a[ru].ad%=mod;
    a[lu].mu=a[lu].mu*a[u].mu;
    a[ru].mu=a[ru].mu*a[u].mu;
    a[lu].mu%=mod,a[ru].mu%=mod;
    a[u].mu=1,a[u].ad=0;
}
void add(int l,int r,int s,int e,int u,int x)
{
    pushdown(u,s,e);
    if(s>=l&&e<=r)
	{
        a[u].su=(a[u].su+x*a[u].dx)%mod;
        a[u].ad=(a[u].ad+x)%mod;
        return;
    }
    int mid=(s+e)>>1,lu=u*2,ru=u*2+1;
    if(l<=mid) add(l,r,s,mid,lu,x);
    if(r>=mid+1) add(l,r,mid+1,e,ru,x);
    a[u].su=(a[lu].su+a[ru].su)%mod;
}
void mul(int l,int r,int s,int e,int u,int x)
{
    pushdown(u,s,e);
    if(s>=l&&e<=r)
	{
        a[u].su=(a[u].su*x)%mod;
        a[u].mu=(a[u].mu*x)%mod;
        a[u].ad=(a[u].ad*x)%mod;
        return;
    }
    int mid=(s+e)>>1,lu=u*2,ru=u*2+1;
    if(l<=mid) mul(l,r,s,mid,lu,x);
    if(r>=mid+1) mul(l,r,mid+1,e,ru,x);
    a[u].su=(a[lu].su+a[ru].su)%mod;
}
int query(int l,int r,int s,int e,int u)
{
    pushdown(u,s,e);
    if(s>=l&&e<=r) return a[u].su;
    int mid=(s+e)>>1,lu=u*2,ru=u*2+1,sum=0;
    if(l<=mid) sum=(sum+query(l,r,s,mid,lu))%mod;
    if(r>=mid+1) sum=(sum+query(l,r,mid+1,r,ru))%mod;
    return sum;
}
signed main()
{
    n=read(),m=read(),mod=read();
    build(1,1,n);
    for(int i=1,op,x,y,k;i<=m;i++)
	{
        op=read(),x=read(),y=read();
        if(op==1) k=read(),mul(x,y,1,n,1,k);
        else if(op==2) k=read(),add(x,y,1,n,1,k);
        else printf("%lld\n",query(x,y,1,n,1));
    }
    return 0;
}
2022/12/4 21:56
加载中...