线段树 区间 + *

 

>>> large ans -> long long  or-> exceed

>>> x<=mid  or -> smalller

 

:::每一次 + * 操作都是 合法合规的 s[].l>=x&&s[].r<=y  对node 操作 else pushdown 因为有 误差

/*
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

17
2
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------debug\n");
using namespace std;
const int maxn=100010;

int n,q,mod,a[maxn];
struct node{
    int l,r;
    ll add,mul,sum;
}s[maxn<<2]; //long long Ö»ÓÃÔÚ ´óÊý¾ÝÉÏ ·ñÔò Òç³ö /Òç³ö 

void build(int k,int l,int r)
{
    s[k].l=l,s[k].r=r,s[k].mul=1  ;
    if(l==r)
    {
        s[k].sum=a[l]%mod;
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    s[k].sum=(s[k<<1].sum+s[k<<1|1].sum)%mod;
}
void pushdown(int k)
{
    if(s[k].add==0&&s[k].mul==1) return;
    
    s[k<<1].sum=( s[k<<1].sum*s[k].mul + (s[k<<1].r-s[k<<1].l+1)*s[k].add )%mod;
    s[k<<1|1].sum=( s[k<<1|1].sum*s[k].mul+ (s[k<<1|1].r-s[k<<1|1].l+1)*s[k].add )%mod;
    
    s[k<<1].mul=s[k<<1].mul*s[k].mul %mod;
    s[k<<1|1].mul=s[k<<1|1].mul*s[k].mul %mod;
    
    s[k<<1].add=(s[k<<1].add*s[k].mul+s[k].add)%mod;
    s[k<<1|1].add=(s[k<<1|1].add*s[k].mul+s[k].add)%mod;
    
    s[k].add=0;
    s[k].mul=1;
}

void areaAdd(int k,int x,int y,int val)
{
    if(s[k].l>y||s[k].r<x) return;
    if(s[k].l>=x&&s[k].r<=y)
    {
        s[k].add=(s[k].add+val)%mod;
        s[k].sum=(s[k].sum+(s[k].r-s[k].l+1)*val )%mod;
        return;
    }
    pushdown(k);
    int mid=s[k].l+s[k].r>>1;
    if(x<=mid) areaAdd(k<<1,x,y,val);
    if(mid<y) areaAdd(k<<1|1,x,y,val);
    s[k].sum=(s[k<<1].sum+s[k<<1|1].sum)%mod;
}
void areaMul(int k,int x,int y,int val)
{
    if(s[k].l>y||s[k].r<x) return;
    if(s[k].l>=x&&s[k].r<=y)
    {
        s[k].add=(s[k].add*val)%mod;
        s[k].sum=(s[k].sum*val )%mod;
        s[k].mul=(s[k].mul*val) %mod;
        return;
    }
    pushdown(k);
    int mid=s[k].l+s[k].r>>1;
    if(x<=mid) areaMul(k<<1,x,y,val);
    if(mid<y) areaMul(k<<1|1,x,y,val);
    s[k].sum=(s[k<<1].sum+s[k<<1|1].sum)%mod;
}

ll query(int k,int x,int y)
{
    if(s[k].l>y||s[k].r<x) return 0;
    if(s[k].l>=x&&s[k].r<=y) return s[k].sum;
    pushdown(k);
    int mid=s[k].l+s[k].r>>1;    ll res=0;
    if(x<=mid) res=(res+query(k<<1,x,y)) %mod;
    if(mid<y) res=(res+query(k<<1|1,x,y)) %mod; // ER mid<=x -> or mid>=x miss
    return res;
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    cin>>n>>q>>mod;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=q;i++)
    {
        int op; cin>>op;
        if(op==1){
            int x,y,k; cin>>x>>y>>k;
            areaMul(1,x,y,k);
        }
        else if(op==2){
            int x,y,k; cin>>x>>y>>k;
            areaAdd(1,x,y,k);
        }
        else if(op==3){
            int x,y; cin>>x>>y;
            //ddd
            cout<<query(1,x,y)%mod<<'\n';
        }
    }
    
    return 0;
}
View Code

 

 
 
 
 
 
posted @ 2023-08-07 01:21  JMXZ  阅读(8)  评论(0)    收藏  举报