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

    分析一下题意:给出一个长度为n的序列,m次操作,单点修改和区间修改,单点查询.

    做法:

    • 差分记录修改
    • 线段树维护区间
    • 查询时输出修改的值加原值

    下面贴一下代码:

    #include<bits/stdc++.h>
    #define ll(x) (x<<1)
    #define rr(x) (x<<1|1)
    using namespace std;
    const int N=100000+5;
    
    int n, m, w[N];
    
    struct segment_tree{
        int l, r, sum, tag;
    }t[N*4];
    
    int gi(){
        int ans = 0 , f = 1; char i = getchar();
        while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
        while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
        return ans * f;
    }
    
    void up(int x){
        t[x].sum = t[ll(x)].sum+t[rr(x)].sum;
    }
    
    void build(int node,int l,int r){
        t[node].l = l; t[node].r = r;
        if(l == r) return;
        int mid = (l+r>>1);
        build(ll(node),l,mid);
        build(rr(node),mid+1,r);
        up(node);
    }
    
    void pushdown(int node){
        int ls = ll(node), rs = rr(node), tag = t[node].tag;
        int l = t[node].l, r = t[node].r , mid = (l+r>>1);
        t[ls].tag += tag; t[rs].tag += tag;
        t[ls].sum += tag*(mid-l+1); t[rs].sum += tag*(r-mid);
        t[node].tag = 0;
    }
    
    void updata(int node,int l,int r,int val){
        if(l <= t[node].l && t[node].r <= r){
        t[node].tag += val;
        t[node].sum += val*(t[node].r-t[node].l+1);
        return;
        }
        if(t[node].tag) pushdown(node);
        int mid = (t[node].l+t[node].r>>1);
        if(l <= mid) updata(ll(node),l,r,val);
        if(mid < r) updata(rr(node),l,r,val);
        up(node);
    }
    
    int query(int node,int l,int r){
        if(l <= t[node].l && t[node].r <= r) return t[node].sum;
        if(r < t[node].l || t[node].r < l) return 0;
        if(t[node].tag) pushdown(node);
        return query(ll(node),l,r)+query(rr(node),l,r);
    }
    
    int main(){
        //freopen("data.in","r",stdin);
        int flag, l, r, k, d; n = gi(); m = gi();
        for(int i=1;i<=n;i++) w[i] = gi();
        build(1,1,n);
        while(m--){
        flag = gi(); l = gi();
        if(flag == 1){
            r = gi(); k = gi(); d = gi();
            updata(1,l+1,r,d); updata(1,l,l,k);
            if(r+1 <= n) updata(1,r+1,r+1,-d*(r-l)-k);//因为建树的时候没有建n+1的下标,所以特判防越界
        }
        else printf("%d
    ",w[l]+query(1,1,l));
        }
        return 0;
    }
    
  • 相关阅读:
    Bootstrap 3 How-To #1 下载与配置
    一致性哈希算法及其在分布式系统中的应用
    哈希(Hash)与加密(Encrypt)的基本原理、区别及工程应用
    ASP.NET MVC3 系列教程
    浏览器对象模型BOM小结
    使用JS实现图片展示瀑布流效果
    利用JS实现购物网站商品放大镜效果
    js事件机制——事件冒泡和捕获
    js入门篇之正则表达式基础
    随机得到1-20之间的10个不相同的随机数
  • 原文地址:https://www.cnblogs.com/BCOI/p/8867637.html
Copyright © 2011-2022 走看看