問題
給出乙個序列\(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...