題解 洛谷P1438 無聊的數列

2021-09-25 19:47:53 字數 1960 閱讀 6278

維護乙個數列,支援兩種操作:

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

這道題很顯然可以用線段樹來做。

但這道題的區間修改是加上乙個等差數列,所以直接硬搞的話會比較困難,需要尋找其他的方法。

這時就很容易能就想到差分了。因為等差數列滿足an=an-1+d,它們的差不變,所以用差分來做會十分簡單。

我們可以將修改分為3部分。

1.對於區間左端點l:

s um

[l]=

sum[

l]+k

sum[l]=sum[l]+k

sum[l]

=sum

[l]+

k2.對於區間的中間部分l+1~r:

s um

[i]=

sum[

i−1]

+d,i

∈(l,

r]

sum[i]=sum[i-1]+d,i\in(l,r]

sum[i]

=sum

[i−1

]+d,

i∈(l

,r]3.對於區間右端點右邊一位r+1:

s um

[r+1

]=su

m[r+

1]−(

k+(r

−l)∗

d)

)sum[r+1]=sum[r+1]-(k+(r-l)*d))

sum[r+

1]=s

um[r

+1]−

(k+(

r−l)

∗d))

對於每次詢問第p個位置的值,答案即為

a [p

]+∑i

=1ps

um[i

]a[p]+\sum_^p sum[i]

a[p]+i

=1∑p

​sum

[i]總結一下,就是要我們對差分陣列進行區間修改+區間求值

這道題在修改的時候要特判兩種情況

1.l=r

這種情況不需要對上述三種中區間的中間部分進行修改。因為此時l+1>r,會越界

2.r=n

這種情況不需要對上述三種中區間右端點右邊一位進行修改。因為此時r+1>n,也會越界

#include#define maxn 100009

using namespace std;

int n,m,a[maxn];

struct node

tr[maxn*5];

void build_tree (int x,int l,int r)

void release (int x)

}void modify (int x,int l,int r,int d)

int mid=(tr[x].l+tr[x].r)>>1,ls=x<<1,rs=(x<<1)+1;

if (l<=mid)

modify(ls,l,r,d);

if (r>=mid+1)

modify(rs,l,r,d);

tr[x].sum=tr[ls].sum+tr[rs].sum;

}long long query (int x,int l,int r)

int main ()

if (op==2)

}return 0;

}

這道題一開始我居然傻傻地想要直接修改,虧最後還是轉過彎來了。太長時間不寫,第一次交了後才發現陣列開小了。真的菜啊qaq

洛谷 P1438 無聊的數列

題目背景 無聊的yyb總喜歡搞出一些正常人無法搞出的東西。有一天,無聊的yyb想出了一道無聊的題 無聊的數列。k峰 這題不是傻x題嗎 題目描述 維護乙個數列,支援兩種操作 1 1 l r k d 給出乙個長度等於r l 1的等差數列,首項為k,公差為d,並將它對應加到a l a r 的每乙個數上。即...

洛谷 P1438 無聊的數列

1 多次對於區間加上乙個等差數列,引數為l,r,k,d,表示首項為k,公差為d,將乙個長度r l 1的等差數列加到區間l.r上 2 詢問乙個值a i 要加上乙個等差數列,很容易想到差分,因此將題目簡化至下 1 將a l 加上k 2 將a l 1.r 加上d 3 將a r 1 r l d k 而查詢的...

洛谷 P1438 無聊的數列

p1438 無聊的數列 題目背景 無聊的yyb總喜歡搞出一些正常人無法搞出的東西。有一天,無聊的yyb想出了一道無聊的題 無聊的數列。k峰 這題不是傻x題嗎 題目描述 維護乙個數列,支援兩種操作 1 1 l r k d 給出乙個長度等於r l 1的等差數列,首項為k,公差為d,並將它對應加到a l ...