冷静 清|

艾特玖

园龄:3年11个月粉丝:12关注:7

P1438 无聊的数列

P1438 无聊的数列

分析

老规矩,先看操作

  • 1 l r K D:给出一个长度等于 r-l+1 的等差数列,首项为 K,公差为 D,并将它对应加到 [l,r] 范围中的每一个数上。即令 al=al+K,al+1=al+1+K+Dar=ar+K+(rl)×D
  • 2 p:询问序列的第 p 个数的值 ap

一看第一个操作,给一个区间的每个数递增的增加数,这妥妥要用差分数组完成啊。

区间修改,单点查询。

我们直接维护差分数组。

操作一:

lK,对[l-1,r]D,对r+1K+(r-l)*D,结束了,记得边界问题。

操作二:

直接查询[1,r]的区间和,即为ap了。

Ac_code

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
struct Node
{
    int l,r;
    LL sum,tag;
}tr[N<<2];
int a[N],b[N];
int n,m;

void pushup(int u)
{
    tr[u].sum = tr[u<<1].sum + tr[u<<1|1].sum;
}

void build(int u,int l,int r)
{
    if(l==r)
    {
        tr[u] = {l,r,b[l],0};
        return;
    }
    tr[u] = {l,r};
    int mid = l + r >> 1;
    build(u<<1,l,mid),build(u<<1|1,mid+1,r);
    pushup(u);
}

void pushdown(int u)
{
    auto &root = tr[u],&left = tr[u<<1],&right = tr[u<<1|1];
    if(root.tag)
    {
        left.sum += 1ll*(left.r - left.l + 1)*root.tag;
        left.tag += root.tag;
        right.sum += 1ll*(right.r - right.l + 1)*root.tag;
        right.tag += root.tag;
        root.tag = 0;
    }
}

void modify(int u,int l,int r,int k)
{
    if(l<=tr[u].l&&tr[u].r<=r) 
    {
        tr[u].sum += 1ll*(tr[u].r - tr[u].l + 1)*k;
        tr[u].tag += k;
        return ;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if(l<=mid) modify(u<<1,l,r,k);
    if(r>mid) modify(u<<1|1,l,r,k);
    pushup(u);
}

LL query(int u,int l,int r)
{
    if(l<=tr[u].l&&tr[u].r<=r) return tr[u].sum;
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    LL res = 0;
    if(l<=mid) res += query(u<<1,l,r);
    if(r>mid) res += query(u<<1|1,l,r);
    return res;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",a+i);
    for(int i=1;i<=n;i++) b[i] = a[i] - a[i-1];
    build(1,1,n);
    while(m--)
    {
        int op;scanf("%d",&op);
        if(op==1)
        {
            int l,r,k,d;scanf("%d%d%d%d",&l,&r,&k,&d);
            modify(1,l,l,k);
            if(r<n) modify(1,r+1,r+1,-k-(r-l)*d);
            if(l<n) modify(1,l+1,r,d);
        } 
        else 
        {
            int p;
            scanf("%d",&p);
            printf("%lld\n",query(1,1,p));
        }
    }
    return 0;
}

本文作者:艾特玖

本文链接:https://www.cnblogs.com/aitejiu/p/16244265.html

版权声明:本作品采用艾特玖许可协议进行许可。

posted @   艾特玖  阅读(51)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起