前字首和 新穎的差分

2022-05-31 12:51:09 字數 1330 閱讀 6989

問題

給出乙個序列\(a[i]\)

字首和\(s=\sum\limits_^a[i]\)

前字首和\(ss=\sum\limits_^s[i]\)

現在給出\(n\)個操作。一些是修改某個\(a[i]\),一些事查詢某個\(ss[i]\)

\(s[i]=a[1]+a[2]+...+a[i]\)

\(ss[i]=s[1]+s[2]+...+s[i]\)

當修改某個\(a[i]\)為\(x\)時,對於\(s\)相當於時給區間\([i,n]\)都加上\(x-a[i]\)

對於\(ss\)而言,相當於給區間\([i,n]\)都加上\(k(x-a[i])\),其中\(k\)是常數,隨著\(i\)的增加而增加

\(然後前面的都是廢話,這題和s序列和差分都沒有什麼關係(手動滑稽)\)

實際上每次查詢\(ss[i]\),答案就是原始的\(ss[i]\)加上期間在區間\([1,i]\)所做的操作的區間和

那麼其實我們維護一下乙個新的序列\(temp\),每次修改\(a[i]\)直接在上面做線段樹修改就行。

#include using namespace std;

typedef long long ll;

const int maxn=100009;

ll n,m;

ll e[maxn],s[maxn],sumn[maxn];

ll ss[maxn],ssumn[maxn],ans[maxn];

struct pa[maxn*4];

void build(ll p,ll l,ll r)

ll mid=l+r>>1;

build(p<<1,l,mid);

build(p<<1|1,mid+1,r);

a[p].w=a[p<<1].w+a[p<<1|1].w;

}void pushdown(int p)

void add(ll p,ll l,ll r,ll k)

pushdown(p);

int mid=a[p].l+a[p].r>>1;

if(mid>=l) add(p<<1,l,r,k);

if(mid=l&&a[p].r<=r)

pushdown(p);

ll mid=a[p].l+a[p].r>>1;

if(mid>=l) ask(p<<1,l,r);

if(mid>n>>m;

for(int i=1;i<=n;i++)

build(1,1,n);

for(int i=1;i<=m;i++)

else

} }

字首和 差分

數列的字首和 sum i 表示a 1 a i 的和 用處1 求i j的和sum j sum i 1 用處2 區間修改。設定乙個change陣列。當區間 i,j 上要加k時,我們令change i k,令change j 1 k。如果我們對change陣列求字首和的話,字首和sum change i ...

字首和 差分

有n個數和q次操作,每一次操作指明了要操作的區間 l,r 以及讓該區間內的所有元素全部加c 輸出q次操作後所有元素的大小 第一行 n q 1 n,q 2 105 第二行 n個數 a1,a2 an 106 ai 106 接下來q 行 每行3個數 l r c 表示 l,r 區間內每個數加c 1 l r ...

字首和 差分

顧名思義 用某乙個陣列來記錄陣列a前i項和,這個還可以用來求區間 l,r 的和 s r s l 1 因為第l項也在區間內 話不多說,直接上例題 leetcode 5393 ac const int maxn 1e5 5 class solution int ans 0 for int i 0 i k...