zoukankan      html  css  js  c++  java
  • P1438 无聊的数列

    题目背景

    无聊的YYB总喜欢搞出一些正常人无法搞出的东西。有一天,无聊的YYB想出了一道无聊的题:无聊的数列。。。(K峰:这题不是傻X题吗)

    题目描述

    维护一个数列{a[i]},支持两种操作:

    1、1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上。即:令a[L]=a[L]+K,a[L+1]=a[L+1]+K+D,

    a[L+2]=a[L+2]+K+2D……a[R]=a[R]+K+(R-L)D。

    2、2 P:询问序列的第P个数的值a[P]。

    输入输出格式

    输入格式:

    第一行两个整数数n,m,表示数列长度和操作个数。

    第二行n个整数,第i个数表示a[i](i=1,2,3…,n)。

    接下来的m行,表示m个操作,有两种形式:

    1 L R K D

    2 P 字母意义见描述(L≤R)。

    输出格式:

    对于每个询问,输出答案,每个答案占一行。

    输入输出样例

    输入样例#1: 
    5 2
    1 2 3 4 5
    1 2 4 1 2
    2 3
    
    输出样例#1: 
    6

    说明

    数据规模:

    0≤n,m≤100000

    |a[i]|,|K|,|D|≤200

    Hint:

    有没有巧妙的做法?

    Solution:

      注意到等差数列公差为$d$,我们可以将原序列差分,设差分后的数组为$sum$,这样对$[l,r]$区间修改等同于对差分后的序列进行如下操作:

      1、$sum[l]+k,;sum[r+1]-k$

      2、$sum[i]+d,;iin [l+1,r],;;sum[r+1]-d(r-l)$

      于是就很自然的可以用线段树维护$sum$数组(差分后的数组),查询第$k$个数等同于查询$a[1,k]$的$sum$和加上原数$a[k]$。

      这样就是区间修改,区间查询的模板了。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int N=100005;
    int n,m,sum[N<<2],add[N<<2],a[N];
    il int gi(){
        int a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-')x=getchar();
        if(x=='-')x=getchar(),f=1;
        while(x>='0'&&x<='9')a=a*10+x-48,x=getchar();
        return f?-a:a;
    }
    il void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
    il void pushdown(int rt,int k){
        if(add[rt]){
            add[rt<<1]+=add[rt];
            add[rt<<1|1]+=add[rt];
            sum[rt<<1]+=add[rt]*(k-(k>>1));
            sum[rt<<1|1]+=add[rt]*(k>>1);
            add[rt]=0;
        }
    }
    il void build(int l,int r,int rt){
        add[rt]=0;
        if(l==r)return;
        int m=l+r>>1;
        build(lson),build(rson);
        pushup(rt);
    }
    il void update1(int L,int R,int c,int l,int r,int rt){
        if(L<=l&&R>=r){
            add[rt]+=c;
            sum[rt]+=c*(r-l+1);
            return ;
        }
        pushdown(rt,r-l+1);
        int m=l+r>>1;
        if(L<=m)update1(L,R,c,lson);
        if(m<R)update1(L,R,c,rson);
        pushup(rt);
    }
    il int query(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r)return sum[rt];
        pushdown(rt,r-l+1);
        int m=l+r>>1;
        int ret=0;
        if(L<=m)ret+=query(L,R,lson);
        if(m<R)ret+=query(L,R,rson);
        return ret;
    }
    int main()
    {
        n=gi(),m=gi();
        for(int i=1;i<=n;i++)a[i]=gi();
        build(1,n,1);
        int f,l,r,k,d;
        while(m--){
            f=gi();
            if(f==1){
                l=gi(),r=gi(),k=gi(),d=gi();
                update1(l+1,r,d,1,n,1);
                update1(l,l,k,1,n,1);
                update1(r+1,r+1,-(k+d*(r-l)),1,n,1);
            }
            else {
                k=gi();
                printf("%d
    ",a[k]+query(1,k,1,n,1));
            }
        }
        return 0;
    }

     

  • 相关阅读:
    printcap
    browser-ua
    PHP 开发 APP 接口 学习笔记与总结
    Java实现 LeetCode 72 编辑距离
    Java实现 LeetCode 72 编辑距离
    Java实现 LeetCode 72 编辑距离
    Java实现 LeetCode 71 简化路径
    Java实现 LeetCode 71 简化路径
    Java实现 LeetCode 71 简化路径
    Java实现 LeetCode70 爬楼梯
  • 原文地址:https://www.cnblogs.com/five20/p/8866604.html
Copyright © 2011-2022 走看看