线段树模板(乘法加法一起处理哦)

来源:互联网 发布:书法坊米芾体字体 mac 编辑:程序博客网 时间:2024/04/30 06:33
这里写代码片#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>using namespace std;struct node{    long long x,y,sum,f,lazy;  //f是加法,lazy是乘法 };node tree[800010];long long n,m,mod,a,b,c,d;long long num[100010];void push(long long bh)  //重点 {    if (tree[bh].lazy==1&&tree[bh].f==0) return;  //没有下放的必要     if (tree[bh].x==tree[bh].y)  //如果是叶子节点,已经做过修改     {  //就把当前状态修改为上一种退出的条件         tree[bh].f=0;        tree[bh].lazy=1;        return;    }     long long ls=bh*2,rs=bh*2+1;    tree[ls].sum=((tree[ls].sum*tree[bh].lazy)%mod+(tree[bh].f*(tree[ls].y-tree[ls].x+1))%mod)%mod;    tree[ls].f=((tree[ls].f*tree[bh].lazy)%mod+tree[bh].f)%mod;    //又注意这里的修改    tree[ls].lazy=(tree[ls].lazy*tree[bh].lazy)%mod;//还有这里<-    tree[rs].sum=((tree[rs].sum*tree[bh].lazy)%mod+(tree[bh].f*(tree[rs].y-tree[rs].x+1))%mod)%mod;    tree[rs].f=((tree[rs].f*tree[bh].lazy)%mod+tree[bh].f)%mod;    tree[rs].lazy=(tree[rs].lazy*tree[bh].lazy)%mod;    tree[bh].f=0;    tree[bh].lazy=1;    return;}void build(long long bh,long long l,long long r){    tree[bh].x=l;    tree[bh].y=r;    tree[bh].lazy=1;    if (l==r)    {        tree[bh].sum=num[l]%mod;        return;    }    build(bh*2,l,(l+r)/2);    build(bh*2+1,(l+r)/2+1,r);    tree[bh].sum=(tree[bh*2].sum+tree[bh*2+1].sum)%mod;}void cheng(long long bh,long long l,long long r,long long z){    push(bh);  //先pushdown     if (tree[bh].y<l||tree[bh].x>r)       return;    if (tree[bh].x>=l&&tree[bh].y<=r)  //完全包含区间     {        tree[bh].lazy=z;        tree[bh].sum=(tree[bh].sum*z)%mod;        return;    }    cheng(bh*2,l,r,z);    cheng(bh*2+1,l,r,z);    tree[bh].sum=(tree[bh*2].sum+tree[bh*2+1].sum)%mod;}void add(long long bh,long long l,long long r,long long z){    push(bh);    if (tree[bh].x>r||tree[bh].y<l)       return;    if (tree[bh].x>=l&&tree[bh].y<=l)    {        tree[bh].f=z;        tree[bh].sum=(tree[bh].sum+((tree[bh].y-tree[bh].x+1)*z)%mod)%mod;        return;    }    add(bh*2,l,r,z);    add(bh*2+1,l,r,z);    tree[bh].sum=(tree[bh*2].sum+tree[bh*2+1].sum)%mod;}long long ask(long long bh,long long l,long long r){    push(bh);    if (tree[bh].x>r||tree[bh].y<l)       return 0;    if (tree[bh].x>=l&&tree[bh].y<=r)       return tree[bh].sum;    long long ans=0;    ans+=ask(bh*2,l,r);    ans+=ask(bh*2+1,l,r);    return ans%mod;}int main(){    scanf("%lld%lld%lld",&n,&m,&mod);    for (int i=1;i<=n;i++)         scanf("%lld",&num[i]);    build(1,1,n);    for (int i=1;i<=m;i++)    {        scanf("%lld%lld%lld",&a,&b,&c);        if (a!=3)           scanf("%lld",&d);        if (a==1)           cheng(1,b,c,d%mod);        else        if (a==2)           add(1,b,c,d%mod);        else           printf("%lld\n",ask(1,b,c));    }    return 0;}
1 0
原创粉丝点击