zoukankan      html  css  js  c++  java
  • 线段树模板(乘法加法一起处理哦)

    这里写代码片
    #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
    ",ask(1,b,c));
        }
        return 0;
    }
  • 相关阅读:
    如何做一个按钮二个事件
    JavaScript中onmouseover时如何让鼠标指针变成一个小手状
    英语口语整理,灵活运用了,口语基本就没问题了
    javascript 传递 '' 时出错 换成 '&' ok
    一个按钮触发两个事件可以吗?
    Select中DISTINCT关键字的用法?
    使下拉框某项不可选的方法
    新打开窗口属性 a href
    调试和测试 Swing 代码
    打造专业外观九宫图
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673656.html
Copyright © 2011-2022 走看看