樹狀陣列模版(單點修改區間求和)(區間修改單點求值)(區間修改區間求和)
阿新 • • 發佈:2019-01-11
eg。
hdu1166(單點修改區間求和)
hdu 1556(區間修改單點求值)#include<bits/stdc++.h> #define maxn 111111 using namespace std; int n; int c[maxn]; int b[maxn]; int lowbit(int x) { return x&-x; } /**單點修改區間求和**/ /** add(x,num); sum(r)-sum(l-1); 每次x號位置修改num 求lr閉區間的和 **/ void add(int k,int num) { while(k<=n) { c[k]+=num; k+=lowbit(k); } } int sum(int k) { int ans=0; while(k) { ans+=c[k]; k-=lowbit(k); } return ans; } int main() { int t; int kase=0; scanf("%d",&t); while(t--) { memset(c,0,sizeof c); printf("Case %d:\n",++kase); scanf("%d",&n); int x,y; for(int i=1;i<=n;i++) { scanf("%d",&x); add(i,x); } char s[10]; while(scanf("%s",s)&&strcmp(s,"End")!=0) { if(strcmp(s,"Query")==0) { scanf("%d%d",&x,&y); printf("%d\n",sum(y)-sum(x-1)); } else { if(strcmp(s,"Add")==0) { scanf("%d%d",&x,&y); add(x,y); } else { scanf("%d%d",&x,&y); add(x,-y); } } } } return 0; }
#include<bits/stdc++.h> #define maxn 111111 using namespace std; int n; int c[maxn]; int b[maxn]; int lowbit(int x) { return x&-x; } /**區間修改單點詢問**/ /** add(l-1,-num);add(r,num); sum(x); 每次修改閉區間lr的值,詢問x節點的值 **/ void add(int k,int num) { while(k) { b[k]+=num; k-=lowbit(k); } } int sum(int k) { int ans=0; while(k<=n) { ans+=b[k]; k+=lowbit(k); } return ans; } int main() { while(scanf("%d",&n)&&(n!=0)) { memset(b,0,sizeof b); int x,y; for(int i=1;i<=n;i++) { scanf("%d%d",&x,&y); add(x-1,-1); add(y,1); } for(int i=1;i<n;i++) { printf("%d ",sum(i)); } printf("%d\n",sum(n)); } return 0; }
自己測試的(區間修改區間求和)
#include<bits/stdc++.h> #define maxn 111111 using namespace std; int n; int c[maxn]; int b[maxn]; int lowbit(int x) { return x&-x; } /**區間修改區間求和**/ /** add_b(r,num);add_c(r,num); if(l>1) { add_b(l-1,-num);add_c(l-1,-num); } sum(r)-sum(l-1); **/ void add_b(int x,int num) { for(int i=x;i>0;i-=lowbit(i)) b[i]+=num; } void add_c(int x,int num) { for(int i=x;i<=n;i+=lowbit(i)) c[i]+=x*num; } int sum_b(int x) { int ans=0; for(int i=x;i<=n;i+=lowbit(i)) ans+=b[i]; return ans; } int sum_c(int x) { int ans=0; for(int i=x;i>0;i-=lowbit(i)) ans+=c[i]; return ans; } int sum(int x) { if(x) return sum_b(x)*x+sum_c(x-1); else return 0; } int main() { char s[10]; memset(b,0,sizeof b); memset(c,0,sizeof c); scanf("%d",&n); while(scanf("%s",s)!=EOF) { int x,y,num; if(strcmp(s,"A")==0) { scanf("%d%d%d",&x,&y,&num); add_b(y,num);add_c(y,num); if(x>1) { add_b(x-1,-num);add_c(x-1,-num); } } else { scanf("%d%d",&x,&y); printf("%d\n",sum(y)-sum(x-1)); } for(int i=1;i<=10;i++) { cout << b[i] << " "; } cout << endl; for(int i=1;i<=10;i++) { cout << c[i] << " "; } cout << endl; } return 0; }