P1438 无聊的数列题解

题目背景

无聊的 YYB 总喜欢搞出一些正常人无法搞出的东西。有一天,无聊的 YYB 想出了一道无聊的题:无聊的数列。。。

题目描述

维护一个数列 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。

若 opt=1 则再输入四个整数 l r K D;

若 opt=2 则再输入一个整数 p。

输出格式

对于每个询问,一行一个整数表示答案。

输入输出样例

输入 #1复制

5 2
1 2 3 4 5
1 2 4 1 2
2 3

输出 #1复制

6

说明/提示

数据规模与约定

对于 100% 数据,0≤n,m≤105,−200≤ai​,K,D≤200,1≤l≤r≤n,1≤p≤n。

思路

直接用线段树维护,细节见代码。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long n,q,a[200005],aa,bb,cc,dd;
long long te[800005],te2[800005],siz[800005],lz[800005],lz2[800005];
char ch;
void ac(long long a1,long long k,long long d){
    te[a1]+=k;
    te2[a1]+=d;
    lz[a1]+=k;
    lz2[a1]+=d;
}
void down(long long a1){
    ac(a1*2,lz[a1],lz2[a1]);
    ac(a1*2+1,lz[a1]+lz2[a1]*siz[a1*2],lz2[a1]);
    lz[a1]=0;
    lz2[a1]=0;
}
void bu(long long a1,long long l,long long r){
    siz[a1]=r-l+1;
    if(l==r){
        te[a1]=a[l];
        te2[a1]=0;
        lz[a1]=0;
        lz2[a1]=0;
        return ;
    }
    long long mid=(l+r)/2;
    bu(a1*2,l,mid);
    bu(a1*2+1,mid+1,r);
    te[a1]=te[a1*2];
    return ;
}
void ci(long long a1,long long l,long long r,long long x,long long y,long long k,long long d){
    if(l>=x&&r<=y){
        te[a1]+=k+d*(l-x);
        te2[a1]+=d;
        lz[a1]+=k+d*(l-x);
        lz2[a1]+=d;
        return ;
    }
    down(a1);
    long long mid=(l+r)/2;
    if(mid>=x){
        ci(a1*2,l,mid,x,y,k,d);
    }
    if(mid+1<=y){
        ci(a1*2+1,mid+1,r,x,y,k,d);
    }
    return ;
}
long long co(long long a1,long long l,long long r,long long x){
    if(x==l&&l==r){
        return te[a1];
    }
    down(a1);
    long long mid=(l+r)/2;
    if(mid>=x){
        return co(a1*2,l,mid,x);
    }
    else{
        return co(a1*2+1,mid+1,r,x);
    }
}
int main(){
    cin>>n>>q;
    for(int i=1;i<=n;i++){
    	cin>>a[i];
	}
    bu(1,1,n);
    for(int i=1;i<=q;i++){
        cin>>ch;
        if(ch=='2'){
            cin>>aa;
            cout<<co(1,1,n,aa)<<endl;
        }
        else{
            cin>>aa>>bb>>cc>>dd;
            ci(1,1,n,aa,bb,cc,dd);
        }
    }
	return 0;
}

posted @ 2025-10-16 20:40  bz02_2023f2  阅读(9)  评论(0)    收藏  举报  来源