zoukankan      html  css  js  c++  java
  • 选拔赛 J题 哭泣的阿木木

    一个模板题,差不多把线段树的板子操作都包括了

    由于使用了过多的Q技能--绷带牵引,阿木木的绷带库存越来越少,有一天,阿木木去市场上采购绷带,市场上的绷带一共有n种,每一种绷带的价格为 aia_iai,由于受到金融危机的影响,绷带的价格出现了一些波动,记性很差的阿木木将绷带价格的波动记录了下来,一共有Q次操作,有时阿木木会记录下新的价格波动,有时阿木木会计算一段区间[L,R]的绷带的价格之和,但是阿木木的计算器一不小心丢了,所以请聪明的你们回答阿木木每次询问的结果。

    已知第i种价格波动有三种形式:

    1. 将区间[L,R]绷带的价格增加k元
    2. 将区间[L,R]绷带的价格减少k元
    3. 将第i种绷带的价格变为 bbb

    每次询问请输出区间[L,R] 内绷带的价格之和

    Input

    第一行输入N和Q(n∈[1,1000000],Q∈[1,1000000])代表N种绷带和Q次询问

    接下来一行N个数ai,表示第i种绷带的价格,(ai∈[1,100000])

    接下来Q次操作:

    q1 L R k 表示将区间[L,R] 内的绷带价格增加k元 (k∈[1,10000],1<=L<R<=n)

    q2 L R k 表示将区间[L,R]内的绷带价格减少k元 (k∈[1,10000],1<=L<R<=n)

    q3 pos b表示将第pos种绷带的价格修改为b (pos∈[1,n],b∈[1,10000],1<=pos<=n)

    q4 L R表示询问区间[L,R]内绷带的价格之和(1<=L<R<=n)

    Output

    输出每次询问的答案

    (请注意过程中绷带的价格可能会变为负数)

    Sample Input 1

    9 9
    10 8 5 7 5 2 6 1 10 
    q3 7 1
    q1 4 7 5
    q2 4 6 7
    q4 1 5
    q2 1 3 7
    q2 3 6 2
    q4 4 9
    q1 4 9 9
    q4 1 8
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    typedef long long ll;
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int maxn = 1000007;
    const int INF=0x7fffffff;
    ll SUM[maxn<<2];
    ll lazy[maxn<<2];
    ll a[maxn];
    void PushUP(ll rt)
    {
        SUM[rt] = SUM[rt<<1] + SUM[rt<<1|1];
    }
    void putdown(ll rt,ll ln,ll rn) {
        if (lazy[rt]) {
            lazy[rt<<1] += lazy[rt];
            lazy[rt<<1|1] += lazy[rt];
            SUM[rt<<1] += lazy[rt] *ln;
            SUM[rt<<1|1] += lazy[rt] * rn;
            lazy[rt] = 0;
        }
    }
    void build(ll l,ll r,ll rt)     //建树
    {
        if (l == r)
        {
            SUM[rt]=a[l];
            return ;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        PushUP(rt);
    }
    void update(int p,int v,int l,int r,int rt)    //单点替换,把p位置的值置为v
    {
        if (l == r)
        {
            SUM[rt] = v;
            return ;
        }
       ll m = (l + r) >> 1;
        putdown(rt,m-l+1,r-m);
        if (p <= m) update(p,v,lson);
        else update(p, v, rson);
        PushUP(rt);
    }
    void update1(ll L,ll R,ll v,ll l,ll r,ll rt)    //将区间L~R的值增加v
    {
        if (L <= l && r <= R)
        {
            lazy[rt] += v;
            SUM[rt] += v * (r - l + 1);
            return ;
        }
        ll m = (l + r) >> 1;
        putdown(rt, m-l+1,r-m);
        if (L <= m) update1(L, R, v, lson);
        if (m < R) update1(L, R, v, rson);
        PushUP(rt);
    }
    ll querySUM(ll L,ll R,ll l,ll r,ll rt)     //求L~R的和
    {
        if (L <= l && r <= R)
        {
            return SUM[rt];
        }
        ll m = (l + r) >> 1;
        putdown(rt,m-l+1,r-m);
        ll ret = 0;
        if (L <= m) ret += querySUM(L, R, lson);
        if (R > m)  ret +=  querySUM(L, R, rson);
        return ret;
    }
    int main()
    {
        int n, m;
        scanf("%d%d",&n,&m);
            for(ll i=1;i<=n;i++)
            {
                 scanf("%lld", &a[i]);
            }
            build(1, n, 1);
            while (m --)
            {
                char op[4];
                ll a,b,c;
                scanf("%s",op);
                if(op[1]=='1')     //区间增加
                {
                    scanf("%lld %lld %lld",&a,&b,&c);
                    update1(a, b, c, 1, n, 1);
                    //for(int i=1;i<=n;i++)
                     //   cout<<SUM[i]<<",";
                   // cout<<endl;
                //cout<<"111"<<endl;
                }
                else if(op[1]=='2')     //区间减少
                {
                     scanf("%lld %lld %lld",&a,&b,&c);
                    update1(a, b, -c, 1, n, 1);
                   // for(int i=1;i<=n;i++)
                    //cout<<SUM[i]<<",";
                    //cout<<endl;
                    //cout<<"222"<<endl;
                }
                else if(op[1]=='3') //单点替换
                {     scanf("%lld %lld",&a,&b);
                    update(a, b, 1, n, 1);
                    //for(int i=1;i<=n;i++)
                    //cout<<SUM[i]<<",";
                   // cout<<endl;
                    //cout<<"3333"<<endl;
                }
                else if(op[1]=='4')   //区间求和
                {
                     scanf("%lld %lld",&a,&b);
                    printf("%lld
    ",querySUM(a, b, 1, n, 1));
                    //for(int i=1;i<=n;i++)
                    //cout<<SUM[i]<<",";
                    //cout<<endl;
                    //cout<<"***"<<endl;
                }
            }
        return 0;
    }
  • 相关阅读:
    项目管理【38】 | 项目人力资源管理-管理项目团队
    转:模型蒸馏,教师学生模型
    转:pytorch 中forward 的用法与解释说明
    KNN, sklearn
    转:matplotlib, 去除plt.savefig()的白边
    转:Latex 表格 合并行/列
    转:LaTeX xcolor颜色介绍
    余弦相似性,cos距离函数
    python confusion matrix 混淆矩阵
    转:Tmux 使用教程
  • 原文地址:https://www.cnblogs.com/tp25959/p/10596534.html
Copyright © 2011-2022 走看看