一維數狀數組區間修改,查詢
阿新 • • 發佈:2017-05-20
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; }
一維數狀數組區間修改,查詢