区间加法,区间查询

复制代码
#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N=1e5+5;

struct SegmentTree {
    int l,r;
    int sum,add;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum(x) tree[x].sum
#define add(x) tree[x].add
} tree[N*4];

int n,m;
int a[N];

void build(int p,int l,int r) {
    l(p)=l,r(p)=r;
    if(l==r) {
        sum(p)=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    sum(p)=sum(p*2)+sum(p*2+1);
}

void spread(int p) {
    if(add(p)) {
        sum(p*2)+=add(p)*(r(p*2)-l(p*2)+1);
        sum(p*2+1)+=add(p)*(r(p*2+1)-l(p*2+1)+1);
        add(p*2)+=add(p);
        add(p*2+1)+=add(p);
        add(p)=0;
    }
}

void change(int p,int l,int r,int d) {
    if(l<=l(p)&&r>=r(p)) {
        sum(p)+=d*(r(p)-l(p)+1);
        add(p)+=d;
        return;
    }
    spread(p);
    int mid=(l(p)+r(p))/2;
    if(l<=mid) change(p*2,l,r,d);
    if(r>mid) change(p*2+1,l,r,d);
    sum(p)=sum(p*2)+sum(p*2+1);
}

int ask(int p,int l,int r) {
    if(l<=l(p)&&r>=r(p)) return sum(p);
    spread(p);
    int mid=(l(p)+r(p))/2;
    int val=0;
    if(l<=mid) val+=ask(p*2,l,r);
    if(r>mid) val+=ask(p*2+1,l,r);
    return val;
}

signed main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
    build(1,1,n);
    while(m--) {
        int op,l,r,d;
        scanf("%lld%lld%lld",&op,&l,&r);
        if(op==1) {
            scanf("%lld",&d);
            change(1,l,r,d);
        } else printf("%lld\n",ask(1,l,r));
    }
    return 0;
}
View Code
复制代码

区间加法乘法,区间查询

复制代码
#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N=1e5+5;

struct SegmentTree {
    int l,r;
    int sum,add,mul=1;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum(x) tree[x].sum
#define add(x) tree[x].add
#define mul(x) tree[x].mul
} tree[N*4];

int n,m,mod;
int a[N];

void build(int p,int l,int r) {
    l(p)=l,r(p)=r;
    if(l==r) {
        sum(p)=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    sum(p)=sum(p*2)+sum(p*2+1);
}

void spread(int p) {
    sum(p*2)=(add(p)*(r(2*p)-l(2*p)+1)%mod+sum(p*2)*mul(p)%mod)%mod;
    sum(p*2+1)=(add(p)*(r(2*p+1)-l(2*p+1)+1)%mod+sum(p*2+1)*mul(p)%mod)%mod;
    add(p*2)=(add(p*2)*mul(p)%mod+add(p))%mod;
    add(p*2+1)=(add(p*2+1)*mul(p)%mod+add(p))%mod;
    mul(p*2)=(mul(p*2)*mul(p))%mod;
    mul(p*2+1)=(mul(p*2+1)*mul(p))%mod;
    add(p)=0;
    mul(p)=1;
}

void chmul(int p,int l,int r,int k) {
    if(l<=l(p)&&r>=r(p)) {
        sum(p)=sum(p)*k%mod;
        add(p)=add(p)*k%mod;
        mul(p)=mul(p)*k%mod;
        return;
    }
    spread(p);
    int mid=(l(p)+r(p))/2;
    if(l<=mid) chmul(p*2,l,r,k);
    if(r>mid) chmul(p*2+1,l,r,k);
    sum(p)=(sum(p*2)+sum(p*2+1))%mod;
}

void chadd(int p,int l,int r,int d) {
    if(l<=l(p)&&r>=r(p)) {
        sum(p)=(sum(p)+d*(r(p)-l(p)+1))%mod;
        add(p)=(add(p)+d)%mod;
        return;
    }
    spread(p);
    int mid=(l(p)+r(p))/2;
    if(l<=mid) chadd(p*2,l,r,d);
    if(r>mid) chadd(p*2+1,l,r,d);
    sum(p)=(sum(p*2)+sum(p*2+1))%mod;
}

int ask(int p,int l,int r) {
    if(l<=l(p)&&r>=r(p)) return sum(p)%mod;
    spread(p);
    int mid=(l(p)+r(p))/2;
    int val=0;
    if(l<=mid) val=(val+ask(p*2,l,r))%mod;
    if(r>mid) val=(val+ask(p*2+1,l,r))%mod;
    return val%mod;
}

signed main() {
    cin>>n>>m>>mod;
    for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
    build(1,1,n);
    while(m--) {
        int op,l,r,k;
        scanf("%lld%lld%lld",&op,&l,&r);
        if(op==1) {
            scanf("%lld",&k);
            chmul(1,l,r,k);
        } else if(op==2) {
            scanf("%lld",&k);
            chadd(1,l,r,k);
        } else printf("%lld\n",ask(1,l,r)%mod);
    }
    return 0;
}
View Code
复制代码

 

posted on   我疯故我在  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】



点击右上角即可分享
微信分享提示