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)。

    输出格式:

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

    线段树维护差分数组即可  

    单点查询就是区间求和

    没有判断 r!=n wa了

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=1e5+5;
    
     ll t[N<<2],col[N<<2];
     int n,m,d,k,x,l,r;
     ll node[N],w[N];
    void up(int pos)
    {
        t[pos]=t[pos<<1]+t[pos<<1|1];
    }
    void build(int l,int r,int pos)
    {
        if(l==r){t[pos]=w[l];return ;}
        int m=(l+r)>>1;build(lson);build(rson);up(pos);
    }
    void down(int pos,int m)
    {
        if(col[pos])
        {
            t[pos<<1]+=(m-(m>>1))*col[pos];
            t[pos<<1|1]+=(m>>1)*col[pos];
            col[pos<<1]+=col[pos];col[pos<<1|1]+=col[pos];
            col[pos]=0;
        }
    }
    void upsum(int L,int R,int v,int l,int r,int pos)
    {
        if(L<=l&&r<=R){ col[pos]+=v;t[pos]+=(r-l+1)*v;return ; }
        int m=(l+r)>>1;down(pos,r-l+1);
        if(L<=m)upsum(L,R,v,lson);if(R>m)upsum(L,R,v,rson);up(pos);
    }
    ll qsum(int L,int R,int l,int r,int pos)
    {
        ll ans=0;if(L<=l&&r<=R)return t[pos];
        int m=(l+r)>>1;down(pos,r-l+1);
        if(L<=m)ans+=qsum(L,R,lson);if(R>m)ans+=qsum(L,R,rson);up(pos);return ans;
    }
    int main()
    {
        RII(n,m);
        rep(i,1,n)cin>>(node[i]);
        rep(i,1,n)w[i]=node[i]-node[i-1];
        build(1,n,1);
    
        while(m--)
        {
            RI(x);
            if(x==1)
            {
                RII(l,r);RII(k,d);
                upsum(l,l,k,1,n,1);
                if(l!=r)upsum(l+1,r,d,1,n,1);
                if(r!=n)upsum(r+1,r+1,-(k+(r-l)*d),1,n,1);
            }
            else
            {
                RI(l);
                printf("%lld
    ",qsum(1,l,1,n,1));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    [LeetCode] 909. Snakes and Ladders 蛇梯棋
    [LeetCode] 857. Minimum Cost to Hire K Workers 雇佣K名工人的最低成本
    [LeetCode] 908. Smallest Range I 最小区间
    [LeetCode] 862. Shortest Subarray with Sum at Least K 和至少为K的最短子数组
    [LeetCode] 907. Sum of Subarray Minimums 子数组最小值之和
    [LeetCode] 864. Shortest Path to Get All Keys 获得所有钥匙的最短路径
    [LeetCode] 906. Super Palindromes 超级回文数
    [LeetCode] 871. Minimum Number of Refueling Stops 最少的加油站个数
    [LeetCode] 905. Sort Array By Parity 按奇偶排序数组
    [LeetCode] 1028. Recover a Tree From Preorder Traversal 从先序遍历还原二叉树
  • 原文地址:https://www.cnblogs.com/bxd123/p/11187490.html
Copyright © 2011-2022 走看看