P1438 无聊的数列

无聊的 YYB 总喜欢搞出一些正常人无法搞出的东西。有一天,无聊的 YYB 想出了一道无聊的题:无聊的数列。。。(K峰:这题不是傻X题吗)
题目描述
维护一个数列 ai​,支持两种操作:
1 l r K D:给出一个长度等于r−l+1 的等差数列,首项为 K,公差为D,并将它对应加到[l,r] 范围中的每一个数上。即:令 al​=al​+K,al+1​=al+1​+K+D…ar​=ar​+K+(r−l)×D。
2 p:询问序列的第 p 个数的值 ap​。
输入格式
第一行两个整数数n,m 表示数列长度和操作个数。
第二行 n 个整数,第 i 个数表示 ai​。
接下来的 m 行,每行先输入一个整数 opt。
若 1opt=1 则再输入四个整数 l r K D;
若 2opt=2 则再输入一个整数 p。
输出格式
对于每个询问,一行一个整数表示答案。
输入
5 2
1 2 3 4 5
1 2 4 1 2
2 3
输出
6

思路

点击查看代码
#include<iostream>
#include<vector>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define N 300020
#define ls u<<1
#define rs u<<1|1
int a[100005]={0};
struct tree
{
   int l,r;
   ll sum,tag;//维护区间和
}tr[N*4];
void pushup(int u)
{
    tr[u].sum=tr[ls].sum+tr[rs].sum;
    return ;
}
void build(int u,int l,int r)
{
    tr[u]={l,r,0,0};
    if(l==r)
   {
       tr[u].sum=a[l];
       //cout<<"l "<<l<<" "<<a[l]<<endl;
       return ;
   }
    int mid=l+r>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(u);
}
void pushdown(int u)
{
    if(tr[u].tag)
    {
      //cout<<"tag "<<tr[u].tag<<endl;
      tr[ls].tag+=tr[u].tag;
      tr[rs].tag+=tr[u].tag;
      ll m=tr[u].l+tr[u].r>>1;
      tr[ls].sum+=(m-tr[u].l+1)*tr[u].tag;
      tr[rs].sum+=(tr[u].r-m)*tr[u].tag;
      tr[u].tag=0;
    }
}

void change(int u,int l,int r,ll y)
{
     if(l<=tr[u].l&&tr[u].r<=r)
        {
            tr[u].tag+=y;
            tr[u].sum+=(tr[u].r-tr[u].l+1)*y;
            return ;
        }
     int m=tr[u].l+tr[u].r>>1;
     pushdown(u);
     if(l<=m)
     change(ls,l,r,y);
     if(r>m)
     change(rs,l,r,y);
     pushup(u);

}
int query(int u,int l,int r)
{
    if(l<=tr[u].l&&tr[u].r<=r)
        return tr[u].sum;
    int m=tr[u].l+tr[u].r>>1;
    ll ans=0;
    pushdown(u);
    if(l<=m) ans=query(ls,l,r);
    if(r>m) ans+=query(rs,l,r);
    pushup(u);
    return ans;
}
signed main()
{
     cin.tie(NULL);
     cout.tie(nullptr);
     ios_base::sync_with_stdio(false);
     int m,n;
     int c,x,y;
     cin>>n>>m;
     for(int i=1;i<=n;i++)
        cin>>a[i];
      for(int i=n;i>0;i--)
        a[i]=a[i]-a[i-1];
        build(1,1,n);
     for(int i=1;i<=m;i++)
     {
       cin>>c;
       if(c==1)
       {
         ll l,r,k,d;
         cin>>l>>r>>k>>d;
         change(1,l,l,k);
         if(l+1<=r)change(1,l+1,r,d);
         if(r<n)change(1,r+1,r+1,-(k+(r-l)*d));
       }
       else {
       int p;
       cin>>p;
       //for(int i=1;i<=n;i++)
       cout<<query(1,1,p)<<'\n';
        }
     }


     return 0;
}

**注意: 思路来自哔哩哔哩董晓算法**
posted @   WandW  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示