線段樹--帶 * + 符號

之後的代碼講解下回見!

#pragma GCC optimize(3)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#define N 100500
using namespace std;
long long MOD,n,m,k,a[N],size[N<<2],add[N<<2],mul[N<<2];
int fuck,x,y;
long long val[4*N];
inline void Build_tree(int left ,int right,int order)
{
    mul[order]=1;
    if(left==right){val[order]=a[left];size[order]=1;return ;}
    int mid=(left+right) >> 1;
    Build_tree(left,mid,order<<1);
    Build_tree(mid+1,right,order<<1|1);
    val[order]=val[order<<1]+val[order<<1|1];
    size[order]=size[order<<1]+size[order<<1|1];
}
inline void Pushdown(int now)
{
    if( !add[now] && !mul[now]) return ;
    add[now<<1]=add[now<<1]*mul[now]%MOD+add[now];
    add[now<<1|1]=add[now<<1|1]*mul[now]%MOD+add[now];
    mul[now<<1]=mul[now<<1]*mul[now]%MOD;
    mul[now<<1|1]=mul[now<<1|1]*mul[now]%MOD;
    val[now<<1]=(val[now<<1]*mul[now]+add[now]*size[now<<1])%MOD;
    val[now<<1|1]=(val[now<<1|1]*mul[now]+add[now]*size[now<<1|1])%MOD;
    add[now]=0; mul[now]=1;
}
inline void adddata(int order,int nowleft,int nowright,int left,int right,long long mark)
{
    if(nowleft > right || nowright < left)return ;
    if(nowleft >=left && nowright <= right){add[order]+=mark;val[order]=(val[order]+size[order]*mark)%MOD;return ;}
    int mid=(nowleft+nowright) >> 1;
    Pushdown(order);
    adddata(order<<1,nowleft,mid,left,right,mark);
    adddata(order<<1|1,mid+1,nowright,left,right,mark);
    val[order]=val[order<<1]+val[order<<1|1];
}
inline void indata(int order,int nowleft,int nowright,int left,int right,long long mark)
{
    if(nowleft > right || nowright < left)return ;
    if(nowleft >=left && nowright <= right){mul[order]*=mark;add[order]*=mark;val[order]=(val[order]*mark)%MOD;return ;}
    int mid=(nowleft+nowright)>>1;
    Pushdown(order);
    indata(order<<1,nowleft,mid,left,right,mark);
    indata(order<<1|1,mid+1,nowright,left,right,mark);
    val[order]=val[order<<1]+val[order<<1|1];
}
inline long long query(int now,int nowleft,int nowright,int left,int right)
{
    if(nowleft > right || nowright < left)return 0;
    if(nowleft >=left && nowright <= right)return val[now];
    Pushdown(now);
    int mid=(nowleft+nowright) >> 1; 
    return  (query(now<<1, nowleft,mid,left,right)+query(now<<1|1,mid+1,nowright,left,right))%MOD;
}
inline long long read()
{
    long long x=0;
    char c=getchar();
    bool flag=0;
    while(c<'0'||c>'9'){if(c=='-')flag=1;   c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?-x:x;
}
int main()
{
    n=read();m=read();MOD=read();
    for(int i=1; i<=n; i++) a[i]=read();
    Build_tree(1,n,1);
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d%d",&fuck,&x,&y);
        if(fuck==1){k=read();indata(1,1,n,x,y,k);}
        else if(fuck==2){k=read();adddata(1,1,n,x,y,k);}
        else printf("%lld\n",query(1,1,n,x,y)%MOD);
    }
    return 0;
}
發佈了57 篇原創文章 · 獲贊 76 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章