• 线段树——I


    老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。

    有长为 nn 的数列,不妨设为 a1,a2,⋯,ana1,a2,⋯,an。有如下三种操作形式:

    • 把数列中的一段数全部乘一个值;
    • 把数列中的一段数全部加一个值;
    • 询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模 PP 的值。

    Input

    第一行两个整数 nn 和 PP;

    第二行含有 nn 个非负整数,从左到右依次为 a1,a2,⋯,ana1,a2,⋯,an;

    第三行有一个整数 MM,表示操作总数;

    从第四行开始每行描述一个操作,输入的操作有以下三种形式:

    • 操作 11:"1 t g c",表示把所有满足 t≤i≤gt≤i≤g 的 aiai 改为 ai×cai×c;
    • 操作 22:"2 t g c",表示把所有满足 t≤i≤gt≤i≤g 的 aiai 改为 ai+cai+c;
    • 操作 33:"3 t g",询问所有满足 t≤i≤gt≤i≤g 的 aiai 的和模 PP 的值。

    同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

    Output

    对每个操作 33,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

    Example

    Input

    7 43
    1 2 3 4 5 6 7
    5
    1 2 5 5
    3 2 4
    2 3 7 9
    3 1 3
    3 4 7
    

    Output

    2
    35
    8
    

    Note

    对于全部测试数据,1≤t≤g≤n,0≤c,ai≤109,1≤P≤1091≤t≤g≤n,0≤c,ai≤109,1≤P≤109。

    样例说明:

    初始时数列为 {1,2,3,4,5,6,7}{1,2,3,4,5,6,7};

    经过第 11 次操作后,数列为 {1,10,15,20,25,6,7}{1,10,15,20,25,6,7};

    对第 22 次操作,和为 10+15+20=4510+15+20=45,模 4343 的结果是 22;

    经过第 33 次操作后,数列为 {1,10,24,29,34,15,16}{1,10,24,29,34,15,16};

    对第 44 次操作,和为 1+10+24=351+10+24=35,模 4343 的结果是 3535;

    对第 55 次操作,和为 29+34+15+16=9429+34+15+16=94,模 4343 的结果是 88。

    memset置换-1,0,inf,意外其他数据会出现bug。学到了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    #define N 410000
    ll sum[N];
    ll a[N];
    ll lazy[N],lazy1[N];
    ll  n,p;
    void build(ll l,ll r,ll rt){//每一步都要mod
        if(l==r){
            sum[rt]=a[l]%p;
            return;
        }
        ll mid=(l+r)/2;
        build(l,mid,rt*2);
        build(mid+1,r,rt*2+1);
        sum[rt]=(sum[rt*2]+sum[rt*2+1])%p;
    }
    void pushdown(ll l,ll r,ll rt){//先更新乘,再更新加
        if(lazy1[rt]!=1){
            sum[rt*2]*=lazy1[rt];
            sum[rt*2]=sum[rt*2]%p;
            sum[rt*2+1]*=lazy1[rt];
            sum[rt*2+1]=sum[rt*2+1]%p;
            lazy1[rt*2]*=lazy1[rt];
            lazy1[rt*2]=lazy1[rt*2]%p;
            lazy1[rt*2+1]*=lazy1[rt];
            lazy1[rt*2+1]=lazy1[rt*2+1]%p;
            lazy[2*rt]*=lazy1[rt];
            lazy[2*rt+1]*=lazy1[rt];
            lazy[2*rt]=lazy[2*rt]%p;
            lazy[2*rt+1]=lazy[2*rt+1]%p;
            lazy1[rt]=1;
        }
        if(lazy[rt]){
            sum[rt*2]+=l*lazy[rt];
            sum[rt*2]=sum[rt*2]%p;
            sum[rt*2+1]+=r*lazy[rt];
            sum[rt*2+1]=sum[rt*2+1]%p;
            lazy[rt*2]+=lazy[rt];
            lazy[rt*2]=lazy[rt*2]%p;
            lazy[rt*2+1]+=lazy[rt];
            lazy[rt*2+1]=lazy[rt*2+1]%p;
            lazy[rt]=0;
        }
    }
    void updatej(ll l1,ll r1,ll v,ll l,ll r,ll rt){//每一步都要pushdown
        if(l1<=l&&r1>=r){
            sum[rt]=sum[rt]+v*(r-l+1);
            sum[rt]=sum[rt]%p;
            lazy[rt]+=v;
            lazy[rt]=lazy[rt]%p;
            return;
        }
        ll mid=(l+r)/2;
        pushdown(mid-l+1,r-mid,rt);
        if(l1<=mid){
            updatej(l1,r1,v,l,mid,rt*2);
        }
        if(r1>mid){
            updatej(l1,r1,v,mid+1,r,rt*2+1);
        }
        sum[rt]=(sum[rt*2]+sum[rt*2+1])%p;
    }
    void updatem(ll l1,ll r1,ll v,ll l,ll r,ll rt){
        if(l1<=l&&r1>=r){
            sum[rt]*=v;
            sum[rt]=sum[rt]%p;
            lazy1[rt]*=v;
            lazy1[rt]=lazy1[rt]%p;
            lazy[rt]*=v;
            lazy[rt]=lazy[rt]%p;
            return;
        }
        ll mid=(l+r)/2;
        pushdown(mid-l+1,r-mid,rt);
        if(l1<=mid){
            updatem(l1,r1,v,l,mid,rt*2);
        }
        if(r1>mid){
            updatem(l1,r1,v,mid+1,r,rt*2+1);
        }
        sum[rt]=(sum[rt*2]+sum[rt*2+1])%p;
    }
    ll query(ll l1,ll r1,ll l,ll r,ll rt){
        if(l1<=l&&r1>=r){
            return sum[rt];
        }
        ll mid=(l+r)/2;
        ll ret=0;
        pushdown(mid-l+1,r-mid,rt);
        if(l1<=mid){
          ret+=query(l1,r1,l,mid,rt*2);
          ret=ret%p;
        }
        if(r1>mid){
            ret+=query(l1,r1,mid+1,r,rt*2+1);
        }
        return ret%p;
    }
    int main()
    {
        for(ll i=1;i<=N;i++){
            lazy1[i]=1;
        }
        memset(lazy,0,sizeof(lazy));
        scanf("%lld %lld",&n,&p);
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        build(1,n,1);
        ll m;
        scanf("%lld",&m);
        while(m--){
            ll a,b,c,d;
            scanf("%lld",&a);
            if(a==1){
                scanf("%lld %lld %lld",&b,&c,&d);
                updatem(b,c,d,1,n,1);
            }
            if(a==2){
                scanf("%lld %lld %lld",&b,&c,&d);
                updatej(b,c,d,1,n,1);
            }
            if(a==3){
                scanf("%lld %lld",&b,&c);
                ll ans=query(b,c,1,n,1);
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    

    举个例子:1-5,+5,*3,如果先乘,就错了

  • 相关阅读:
    Deep Learning入门视频(下)之关于《感受神经网络》两节中的代码解释
    Deep Learning入门视频(上)_一层/两层神经网络code
    第一百五十三节,封装库--JavaScript,表单验证--备注字数验证
    第一百五十二节,封装库--JavaScript,表单验证--年月日注入
    第一百五十一节,封装库--JavaScript,表单验证--密码确认验证--回答验证--电子邮件验证加自动补全
    第一百五十节,封装库--JavaScript,表单验证--密码验证
    第一百四十九节,封装库--JavaScript,表单验证--验证用户名
    第一百四十八节,封装库--JavaScript,菜单切换
    第一百四十七节,封装库--JavaScript,滑动导航
    第一百四十六节,JavaScript,百度分享保持居中--下拉菜单
  • 原文地址:https://www.cnblogs.com/skyleafcoder/p/12319550.html
Copyright © 2020-2023  润新知