萌新刚学线段树,请问爆负数怎么办?
查看原帖
萌新刚学线段树,请问爆负数怎么办?
414386
Isshiki·Iroha楼主2021/10/8 09:37

我能 % 的都 % 了

#include<bits/stdc++.h>
#define ll long long
using namespace std;
namespace Mashiro {
    char buf[1<<18],*p1=buf,*p2=buf;
    inline int getc() {
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<18,stdin),p1==p2)?EOF:*p1++;
    }
#ifndef ONLINE_JUDGE
    #define getc() getchar()
#endif
    template<typename T>inline void read(T& x) {
        x=0;int f=1;
        char ch=getc();
        while(!isdigit(ch)){if(ch=='-')f=~f+1;ch=getc();}
        while (isdigit (ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getc();}
        x*=f;
    }
    template <typename T,typename... Args> inline void read(T& x, Args&... args) {
        read(x);
        read(args...);
    }
    char buffer[1<<18];int p11=-1;const int p22=(1<<18)-1;
    inline void flush() {fwrite(buffer,1,p11+1,stdout),p11=-1;}
    inline void putc(const char &x) {if (p11==p22) flush();buffer[++p11]=x;}
    template<typename T>inline void write(T x) {
        static int buf[40],top=0;
        if(x<0)putc('-'),x=~x+1;
        while(x)buf[++top]=x%10,x/=10;
        if(top==0)buf[++top]=0;
        while (top) putc(buf[top--]^48);
        putc(' ');
        flush();
     }
     template <typename T,typename... Args> inline void write(T x, Args... args) {
         write(x);
         write(args...);
     }
}
using namespace Mashiro;
const int maxn=1e5+10;
ll Mod;
int n,m;
ll a[maxn];
struct tree{
    ll sum,add,mul;
    tree(){
        add=0;
        mul=1;
    }
}segt[maxn<<2];
namespace segment_tree{
    #define ls k<<1
    #define rs k<<1|1
    void build(int k,int l,int r){
        if(l==r){
            segt[k].sum=a[l]%Mod;
            return;
        }
        int mid=l+r>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        segt[k].sum=segt[ls].sum+segt[rs].sum;
        segt[k].sum%=Mod;
    }
    inline void update(int k,int l,int r,ll add,ll mul){
        segt[k].sum=(segt[k].sum*mul%Mod+add*(r-l+1)%Mod)%Mod;
        segt[k].mul*=mul%Mod;
        segt[k].add=(segt[k].add*mul%Mod+add)%Mod;
    }
    inline void pushdown(int k,int l,int r){
        int mid=l+r>>1;
        update(ls,l,mid,segt[k].add,segt[k].mul);
        update(rs,mid+1,r,segt[k].add,segt[k].mul);
        segt[k].mul=1;
        segt[k].add=0;
    }
    void modity_add(int k,int l,int r,int x,int y,ll add){
        if(l>=x&&r<=y){
            update(k,l,r,add,1ll);
            return;
        }
        if(l>y||r<x)return;
        pushdown(k,l,r);
        int mid=l+r>>1;
        if(mid>=x)modity_add(ls,l,mid,x,y,add);
        if(mid+1<=y)modity_add(rs,mid+1,r,x,y,add);
        segt[k].sum=(segt[ls].sum+segt[rs].sum)%Mod;
    }
    void modity_mul(int k,int l,int r,int x,int y,ll mul){
        if(l>=x&&r<=y){
            update(k,l,r,0ll,mul);
            return;
        }
        if(l>y||r<x)return;
        int mid=l+r>>1;
        pushdown(k,l,r);
        if(mid>=x)modity_mul(ls,l,mid,x,y,mul);
        if(mid+1<=y)modity_mul(rs,mid+1,r,x,y,mul);
        segt[k].sum=(segt[ls].sum+segt[rs].sum)%Mod;
    }
    ll query(int k,int l,int r,int x,int y){
        if(l>=x&&r<=y)return segt[k].sum%Mod;
        if(l>y||r<x)return 0;
        int mid=l+r>>1;
        ll ans=0;
        pushdown(k,l,r);
        if(mid>=x)(ans+=(query(ls,l,mid,x,y)%Mod))%=Mod;
        if(mid+1<=y)((ans+=query(rs,mid+1,r,x,y))%Mod)%Mod;
        return ans%Mod;
    }
}
using namespace segment_tree;
int main() {
    read(n,m,Mod);
    for(int i(1);i<=n;++i)read(a[i]),a[i]%=Mod;
    build(1,1,n);
    ll k;
    for(int i(1),opt,x,y;i<=m;++i){
        read(opt,x,y);
        if(opt==1){
            read(k);
            modity_mul(1,1,n,x,y,k%Mod);
        }
        else if(opt==2){
            read(k);
            modity_add(1,1,n,x,y,k%Mod);
        }
        else {
            write(query(1,1,n,x,y)%Mod);
            putc('\n');
        }
    }
    return 0;
}

2021/10/8 09:37
加载中...