洛谷P1438 無聊的數列

2022-05-31 03:54:08 字數 1728 閱讀 5364

題目型別:差分,線段樹

傳送門:>here

<

所謂差分,我個人的理解就是用\(o(1)\)的方法來維護字首和,當然查詢變為了\(o(n)\)。差分就好像將字首和變成了乙個數一樣——當一段區間需要全部加上\(k\)時:差分陣列某一位上\(+k\),意味著這之後的所有元素都將\(+k\)。就好像一條帶子拖到最後了。因此我們如果僅僅操作乙個區間的話,那麼要把後面多出來的帶子減掉,於是我們再另外加一條負的帶子在後面。

剛才談論整個區間都加乙個相同的數。如果整個區間加的是乙個等差數列呢?相當於這個區間內所加的數,每個都比前面的多加\(d\)。效果就等價於在差分陣列中,令這個區間的每個元素加上\(d\)。然後末尾要減去末項。依然使用剛才的比喻,將那麼多條相同的帶子依次疊放,假設區間長度是\(l\),那麼最後乙個元素那裡肯定放著\(l\)條帶子了。而我們在最後需要把這\(l\)條帶子全部減掉。

因此,如果用差分來維護這道題,我們來總結一下步驟:(按照題意,等差數列的更新方法是\(l \ r \ k \ d\),代表左端點,右端點,首項,公差;設差分陣列為\(s\))

由此我們發現,對於大多數的情況都是\(+d\),因此轉化為乙個區間更新的問題。差分陣列的統計方法我們已經很熟悉了,需要從頭遍歷。因此元素\(p\)現在的值應該是:初始值 + \(s[1..p]\),因此轉化為乙個區間查詢的問題

因此我們可以用線段樹方便地\(o(logn)\)維護好

一直以為差分和線段樹維護的幾乎是同乙個東西,卻從來沒想過線段樹可以用來維護差分!線段樹維護差分,就好像求和的和。然而等差數列就好像是三維的一樣,先由差分轉化為二維,然後由線段樹轉化為線性。

正好像我們在找規律時所作的一樣,差,差之差,差之差之差。那麼這道題就好像倒過來,和,和的和,和的和的和……

不需要建樹,線段樹寫起來好像異常短小精悍……\(qwq\)

/*by dennyqi 2018*/

#include #include #include #include using namespace std;

typedef long long ll;

const int maxn = 100010;

const int inf = 1061109567;

inline int max(const int a, const int b)

inline int min(const int a, const int b)

inline int read()

int n,m,opt,l,r,x,y;

int a[maxn];

int val[maxn<<2],lazy[maxn<<2];

struct segmenttree

} int query(int rt, int l, int r, int x, int y)

void update(int rt, int l, int r, int x, int y, int k)

pushdown(rt,l,r);

int mid = (l+r)/2;

update(rt<<1,l,mid,x,y,k), update(rt<<1|1,mid+1,r,x,y,k);

val[rt] = val[rt<<1] + val[rt<<1|1];

}}qxz;

int main()

while(m--)

else

} return 0;

}

洛谷 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 ...