對於已知有n個元素的離線數列d,咱們能夠創建記錄它每項與前一項差值的差分數組f:顯然,f[1]=d[1]-0=d[1];對於整數i∈[2,n],咱們讓f[i]=d[i]-d[i-1]。html
(1)計算數列各項的值:觀察d[2]=f[1]+f[2]=d[1]+d[2]-d[1]=d[2]可知,數列第i項的值是能夠用差分數組的前i項的和計算的,即d[i]=f[i]的前綴和。
(2)計算數列每一項的前綴和:第i項的前綴和即爲數列前i項的和,那麼推導可知
便可用差分數組求出數列前綴和;ios
假如如今對數列中區間[L,R]上的數加上x,咱們經過性質(1)知道,第一個受影響的差分數組中的元素爲f[L],即令f[L]+=x,那麼後面數列元素在計算過程當中都會加上x;最後一個受影響的差分數組中的元素爲f[R],因此令f[R+1]-=x,便可保證不會影響到R之後數列元素的計算。這樣咱們沒必要對區間內每個數進行處理,只需處理兩個差分後的數便可;數組
由性質(2)咱們能夠計算出數列各項的前綴和數組sum各項的值;那麼顯然,區間[L,R]的和即爲ans=sum[R]-sum[L-1];數據結構
-N個氣球排成一排,從左到右依次編號爲1,2,3....N.每次給定2個整數a b(a <= b),lele便爲騎上他的「小飛鴿"牌電動車從氣球a開始到氣球b依次給每一個氣球塗一次顏色。可是N次之後lele已經忘記了第I個氣球已經塗過幾回顏色了,你能幫他算出每一個氣球被塗過幾回顏色嗎?
-Input:每一個測試實例第一行爲一個整數N,(N <= 100000).接下來的N行,每行包括2個整數a b(1 <= a <= b <= N)。當N = 0,輸入結束。
-Output:每一個測試實例輸出一行,包括N個整數,第I個數表明第I個氣球總共被塗色的次數。測試
1.記錄各次操做,對差分數組進行對應修改,改變量爲1(用途1);
2.使用性質(1)計算各項的值便可;spa
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; int d[100010],a[100010],l,r; int main(){ int n; while(scanf("%d",&n),n) { memset(d,0,sizeof(d)); memset(a,0,sizeof(a)); for(int i=1;i<=n;++i){ scanf("%d%d",&l,&r); d[l]+=1; d[r+1]-=1; } for(int i=1;i<=n;++i) a[i]=a[i-1]+d[i]; for(int i=1;i<n;++i) printf("%d ",a[i]); printf("%d\n",a[n]); } return 0; }
-給定一個長度爲N的序列,首先進行A次操做,每次操做在Li和Ri這個區間加上一個數Ci。
而後有B次詢問,每次詢問Li到Ri的區間和。
初始序列都爲0。
-輸入格式:
第一行三個整數N A B。(1<=N<=1000000,1<=A<=N,A<=B<=N)
接下來A行,每行三個數Li Ri Ci。(1<=Li<=N,Li<=Ri<=N,|Ci|<=100000000000000)。
接下來B行,每行兩個數 Li Ri。範圍同上。
-輸出格式:
對於每次詢問,輸出一行一個整數。
由於最後的結果可能很大,請對結果mod 1000000007。code
1.應用(1)處理區間加;
2.用性質(1)求出修改後數列,再求出相應數列和(應用2)或直接用性質(2)求解;
3.注意隨時取模;htm
#include<iostream> #include<cmath> #include<cstring> #include<algorithm> #include<cstdio> const long long mod=1000000007; using namespace std; long long d[100010],f[100010],sum[100010]; int main(){ int n,a,b; scanf("%d%d%d",&n,&a,&b); memset(d,0,sizeof(d)); memset(f,0,sizeof(f)); memset(sum,0,sizeof(sum)); for(int i=1;i<=a;++i){ long long l,r,c; scanf("%ld%ld%ld",&l,&r,&c); f[l]=(f[l]+c)%mod; f[r+1]=(f[r+1]-c)%mod; } for(int i=1;i<=n;++i) d[i]=(d[i-1]+f[i])%mod; for(int i=1;i<=n;i++) sum[i]=(sum[i-1]+d[i])%mod; for(int i=1;i<=b;++i){ int l,r; scanf("%d%d",&l,&r); printf("%ld\n",(sum[r]-sum[l-1])%mod); //printf("%ld\n",temp>=0?temp:temp+mod);//防止結果爲負; } return 0; }