AcWing242一個簡單的整數問題1(差分+樹狀陣列)
阿新 • • 發佈:2020-08-26
題目地址:https://www.acwing.com/problem/content/248/
題目描述
給定長度為N的數列A,然後輸入M行操作指令。
第一類指令形如“C l r d”,表示把數列中第l~r個數都加d。
第二類指令形如“Q X”,表示詢問數列中第x個數的值。
對於每個詢問,輸出一個整數表示答案。
輸入格式
第一行包含兩個整數N和M。
第二行包含N個整數A[i]。
接下來M行表示M條指令,每條指令的格式如題目描述所示。
輸出格式
對於每個詢問,輸出一個整數表示答案。
每個答案佔一行。
資料範圍
1≤N,M≤1e5
|d|≤10000,
|A[i]|≤1000000000
題解:樹狀陣列可以額解決的是單點修改和區間求和問題。這道題是區間修改和單點求值。那麼就需要和差分陣列來一起進行。差分陣列是在原先的陣列a的基礎上進行差分的,差分陣列b[i]=a[i]-a[i]-1,所以區間[l,r]修改就相當於b[l]+=d,b[r+1]-=d,單點求值就是對差分陣列進行字首和求值
AC程式碼:
#include<iostream> using namespace std; const int N=1e5+10; #define ll long long int #define lowbit(x) (x&-(x)) ll c[N]={0},n,m,a[N]={0}; void add(int x,ll d){ while(x<=n){ c[x]+=d; x+=lowbit(x); } } ll sum(int x){ ll sum=0; while(x>0){ sum+=c[x]; x-=lowbit(x); } return sum; } int main(){ cin>>n>>m; ll now=0,x; for(int i=1;i<=n;i++){ cin>>x; a[i]=x-now; now=x; } for(int i=1;i<=n;i++) add(i,a[i]); char ch; ll l,r,d; while(m--){ cin>>ch; if(ch=='C'){ cin>>l>>r>>d; add(l,d); add(r+1,-d); } else { cin>>x; cout<<sum(x)<<endl; } } return 0; }
寫於:202/8/26 13:03