1. 程式人生 > >一維數狀數組區間修改,查詢

一維數狀數組區間修改,查詢

int strong bit 操作 owb codevs ++ fin 正整數

模板題CODEVS-1082

給你N個數,有兩種操作:

1:給區間[a,b]的所有數增加X

2:詢問區間[a,b]的數的和。

第一行一個正整數n,接下來n行n個整數,

再接下來一個正整數Q,每行表示操作的個數,

如果第一個數是1,後接3個正整數,

表示在區間[a,b]內每個數增加X,如果是2,

表示操作2詢問區間[a,b]的和是多少。

一維樹狀數組可以考慮用差分來做,但是擴展不到二維。

所以我們令di=(ai~an)的增量

思路和差分一樣,可以擴展到二維(現在還沒懂)

#include<iostream>
#include
<cstdio> #include<algorithm> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; #define lowbit(x) x&(-x) int n,m,a[1000005],c1[1000005],c2[1000005]; void update(int v,int val) { for(int pp=v;pp<=n;c1[pp]+=val,c2[pp]+=val*v,pp+=lowbit(pp)); } int query(int l,int r) {
int ans=0; for(int pp=r;pp>0;ans+=(r+1)*c1[pp],ans-=c2[pp],pp-=lowbit(pp)); l--; for(int pp=l;pp>0;ans-=(l+1)*c1[pp],ans+=c2[pp],pp-=lowbit(pp)); return ans; } int main() { scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for
(int i=1;i<=n;i++) update(i,a[i]-a[i-1]); for(int i=1;i<=m;i++) { int p,l,r,val; scanf("%d %d %d",&p,&l,&r); if(p==1) { scanf("%d",&val); update(l,val); update(r+1,-val); }else { printf("%d\n",query(l,r)); } } return 0; }

一維數狀數組區間修改,查詢