记录编号 585550 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [SYOI 2018] 简单的线段树 最终得分 100
用户昵称 Gravatar┭┮﹏┭┮ 是否通过 通过
代码语言 C++ 运行时间 12.368 s
提交时间 2023-12-16 16:41:35 内存使用 0.00 MiB
显示代码纯文本
#include <bits/stdc++.h> 
using namespace std;
#define ll long long
const int N = 1e5+10;
ll n,m,p;
ll a[N];
struct SegentTree{
    int l,r;
    ll sum,add,mul;
    #define l(x) t[x].l
    #define r(x) t[x].r
    #define sum(x) t[x].sum
    #define add(x) t[x].add
    #define mul(x) t[x].mul
}t[N<<2];
void pushup(int x){
    sum(x) = (sum(x<<1) + sum(x<<1|1)) % p;
}
void pushdown(int x){
    if(mul(x) != 1){
        mul(x<<1) = (mul(x<<1) * mul(x)) % p;
        mul(x<<1|1) = (mul(x<<1|1) * mul(x)) % p;
        sum(x<<1) = (sum(x<<1) * mul(x)) % p;
        sum(x<<1|1) = (sum(x<<1|1) * mul(x)) % p; 
        add(x<<1) = (add(x<<1) * mul(x)) % p;
        add(x<<1|1) = (add(x<<1|1) * mul(x)) % p;
        mul(x) = 1;
    }//!!
    if(add(x) != 0){
        add(x<<1) = (add(x<<1) + add(x)),add(x<<1|1) = (add(x<<1|1) + add(x)) % p;
        sum(x<<1) = (sum(x<<1) + add(x) * (r(x<<1) - l(x<<1) + 1) % p) % p;
        sum(x<<1|1) = (sum(x<<1|1) + add(x) * (r(x<<1|1) - l(x<<1|1) + 1) % p) % p;
        add(x) = 0;
    }
}
void build(int x,int l,int r){
    l(x) = l,r(x) = r;mul(x) = 1;
    if(l == r){
        sum(x) = a[l] % p;
        return;
    }
    int mid = l + r >> 1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    pushup(x);
}
void modifyadd(int x,int l,int r,ll z){
    if(l <= l(x) && r(x) <= r){
        add(x) = (add(x) + z) % p;
        sum(x) = (sum(x) + z * (r(x) - l(x) + 1) % p) % p;
        return;
    }
    pushdown(x);
    int mid = l(x) + r(x) >> 1;
    if(l <= mid)modifyadd(x<<1,l,r,z);
    if(r > mid)modifyadd(x<<1|1,l,r,z);
    pushup(x);
}
void modifymul(int x,int l,int r,ll z){
    if(l <= l(x) && r(x) <= r){
        mul(x) = (mul(x) * z) % p;
        add(x) = (add(x) * z) % p;
        sum(x) = (sum(x) * z) % p;
        return;
    }
    pushdown(x);
    int mid = l(x) + r(x) >> 1;
    if(l <= mid)modifymul(x<<1,l,r,z);
    if(r > mid)modifymul(x<<1|1,l,r,z);
    pushup(x);
}
ll ask(int x,int l,int r){
    if(l <= l(x) && r(x) <= r)return sum(x);
    pushdown(x);
    int mid = l(x) + r(x) >> 1;ll ans = 0;
    if(l <= mid)ans = (ans + ask(x<<1,l,r)) % p;
    if(r > mid)ans = (ans + ask(x<<1|1,l,r)) % p;
    return ans;
}
int main(){
    freopen("easilysegmenttree.in","r",stdin);
    freopen("easilysegmenttree.out","w",stdout);
    scanf("%lld%lld%lld",&n,&m,&p);
    build(1,1,n);
    for(int i = 1;i <= m;i++){
        int op,x,y;ll z;
        scanf("%d%d%d",&op,&x,&y);
        if(op == 2){
            scanf("%lld",&z);
            modifymul(1,x,y,z);
        }
        else if(op == 1){
            scanf("%lld",&z);
            modifyadd(1,x,y,z);
        }
        else printf("%lld\n",ask(1,x,y));
    }
    
    return 0;
    
}