洛谷OJ P3368 【模板】樹狀陣列 2
阿新 • • 發佈:2019-02-17
題目思路:區間更新,單點查詢模板題,樹狀陣列做法
AC程式碼:
#include<cstdio> #include<cmath> #include<cstring> #include<string> #include<cstdlib> #include<algorithm> #include<iostream> #include<queue> #include<stack> #include<map> using namespace std; #define FOU(i,x,y) for(int i=x;i<=y;i++) #define FOD(i,x,y) for(int i=x;i>=y;i--) #define MEM(a,val) memset(a,val,sizeof(a)) #define PI acos(-1.0) const double EXP = 1e-9; typedef long long ll; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const ll MINF = 0x3f3f3f3f3f3f3f3f; const double DINF = 0xffffffffffff; const int mod = 1e9+7; const int N = 1e6+5; //一維樹狀陣列區間修改,單點查詢 //原來的值存在a[]裡面,多建立個數組c1[](程式碼中用tree陣列表示),注意:c1[i]=a[i]-a[i-1]。 //那麼求a[i]的值的時候a[i]=a[i-1]+c1[i]=a[i-2]+c1[i]+c1[i-1]=…..=c1[1]+c1[2]+…+c1[i]。 int a[N],tree[N]; int n; int lowbit(int x){return x&(-x);} void updata(int x,int val){ //單點更新 while(x<=n){ tree[x]+=val; x+=lowbit(x); } } void regionUpdata(int x,int y,int val){ //區間更新,實現a[x]~a[y]+val updata(x,val); updata(y+1,-val); } int pointQuery(int x){ //單點查詢,因為tree陣列是差分陣列,所以a[x]=tree[1]+tree[2]+...+tree[x] int ans=0; while(x>0){ ans+=tree[x]; x-=lowbit(x); } return ans; } void init(){ a[0]=0; for(int i=1;i<=n;i++){ updata(i,a[i]-a[i-1]); //用差分陣列初始化樹狀陣列 } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); std::ios::sync_with_stdio(false); int q,x,y,val,typ; scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&a[i]); init(); while(q--){ scanf("%d",&typ); if(typ==1){ scanf("%d%d%d",&x,&y,&val); regionUpdata(x,y,val); } else{ scanf("%d",&x); printf("%d\n",pointQuery(x)); } } return 0; }