蒟蒻全WA求调
查看原帖
蒟蒻全WA求调
1023140
dedseclossr楼主2023/8/23 19:53
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX = 1e5+10;
int num[MAX];
int n,m,mod;
struct segTree
{
    int left,right;
    ll value,mark,mul;
}bt[MAX*4];

inline void build(int le,int ri,int p)    //p是线段树的节点索引,le和ri是原数组的索引
{
    bt[p].left = le,bt[p].right = ri,bt[p].mark = 0, bt[p].mul = 1;
    if(le==ri) bt[p].value = num[le];
    else
    {
        int mid = (le+ri)>>1;
        build(le,mid,p<<1);
        build(mid+1,ri,p<<1|1);
        bt[p].value = bt[p<<1].value + bt[p<<1|1].value;
    }
}

inline void push_down(int p)   //懒标记的传递,维护已发生的操作
{
        int len = bt[p].right - bt[p].left + 1;

        bt[p<<1].value = (bt[p].mark*(len-len/2) + bt[p<<1].value*bt[p].mul)%mod;
        bt[p<<1|1].value = (bt[p].mark*(len>>1) + bt[p<<1|1].value*bt[p].mul)%mod;

        bt[p<<1].mul = (bt[p<<1].mul * bt[p].mul)%mod;
        bt[p<<1|1].mul = (bt[p<<1].mul*bt[p].mul)%mod;

        bt[p<<1].mark = (bt[p<<1].mark*bt[p].mul + bt[p].mark)%mod;
        bt[p<<1|1].mark = (bt[p<<1|1].mark*bt[p].mul + bt[p].mark)%mod;

        bt[p].mark = 0;
        bt[p].mul = 1;
}

void add(int d,int p,int l,int r) //l、r代表目标区间,d代表目标区间每个点所要加的值
{
    if(bt[p].left>r||bt[p].right<l) return ;   //当前区间与目标区间无交集,直接剪掉
    else if(bt[p].left>=l&&bt[p].right<=r)      //当前区间被目标区间覆盖,直接修改区间,递归结束
    {
        bt[p].value = (bt[p].value + (bt[p].right-bt[p].left+1)*d)%mod ;
        if(bt[p].left<bt[p].right) bt[p].mark  = (bt[p].mark+d)%mod;
    }
    else                                      //在有交集的情况下,需继续向下递归寻找目标区间,同时维护已发生的操作。
    {
        push_down(p);
        add(d,p<<1,l,r);
        add(d,p<<1|1,l,r);
        bt[p].value = (bt[p<<1].value + bt[p<<1|1].value)%mod;
    }
}

void multi(int d,int p,int l,int r)
{
    if(bt[p].left>r||bt[p].right<l) return ;
    else if(bt[p].left>=l&&bt[p].right<=r)
    {
        bt[p].mark = (bt[p].mark*d)%mod;
        bt[p].value = (bt[p].value*d)%mod;
        bt[p].mul = (bt[p].mul*d)%mod;
    }
    else
    {
        push_down(p);
        multi(d,p<<1,l,r);
        multi(d,p<<1|1,l,r);
        bt[p].value = (bt[p<<1].value + bt[p<<1|1].value)%mod;
    }
}

ll query(int p,int l,int r)
{
    if(bt[p].left>r||bt[p].right<l) return 0;   //当前区间与目标区间无交集,直接剪掉
    else if(bt[p].left>=l&&bt[p].right<=r) return bt[p].value;
    else
    {
        push_down(p);
        return (query(p<<1,l,r) + query(p<<1|1,l,r))%mod;
    }
}

main()
{
    cin>>n>>m>>mod;
    for(int i=1;i<=n;i++) cin>>num[i];
    build(1,n,1);
    while(m--)
    {
        int order,x,y,k;
        scanf("%d",&order);
        if(order==1)
        {
            scanf("%d%d%d",&x,&y,&k);
            multi(k,1,x,y);
        }
        else if(order==2)
        {
            scanf("%d%d%d",&x,&y,&k);
            add(k,1,x,y);
        }
        else
        {
            scanf("%d%d",&x,&y);
            cout<<query(1,x,y)<<endl;
        }
    }
    return 0;
}


2023/8/23 19:53
加载中...