Codeforces Round #248 (Div. 2) B題 【資料結構:樹狀陣列】
阿新 • • 發佈:2018-12-23
題目大意:給n(1 ≤ n ≤ 105)個數據(1 ≤ vi ≤ 109),其中有m(1 ≤ m ≤ 105)個問題,分兩種,第一種:給出l,r,讓你求出v[l],v[r]之間的所有資料和;第二種:先將原資料升序排序得到vv陣列,給出l,r,讓你求出vv[l],vv[r]之間的所有資料和;
此題如果用暴力求解,由於資料太大,會TLE,所以利用樹狀陣列,快速求解區間和的問題。
如果不懂樹狀陣列,可以去看看關於資料結構的知識
程式碼:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; int v[100011]; int vv[100011]; long long Cv[100011];// 每個C陣列代表v[i-lowbit(i)+1]到v[i]之間的和 long long Cvv[100011]; int lowbit(int x) { return x&(x^(x-1)); } long long Sumv(int i) //求出陣列v[1]到v[i]的和 { long long result=0; while (i>=1) { result+=Cv[i]; i-=lowbit(i); } return result; } long long Sumvv(int i) //求出陣列vv[1]到vv[i]的和 { long long result=0; while (i>=1) { result+=Cvv[i]; i-=lowbit(i); } return result; } int main() { int n,m,t,l,r; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&v[i]); vv[i]=v[i]; } sort(vv,vv+n+1); for(int i=1;i<=n;i++) { for(int j=i-lowbit(i)+1;j<=i;j++) Cv[i]+=v[j]; for(int j=i-lowbit(i)+1;j<=i;j++) Cvv[i]+=vv[j]; } scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%d%d%d",&t,&l,&r); if(t==1) { printf("%I64d\n",Sumv(r)-Sumv(l-1)); } else { printf("%I64d\n",Sumvv(r)-Sumvv(l-1)); } } return 0; }
此題也可以不用樹狀陣列,可以用s[i]陣列代表v[1]到v[i]的所有資料和,要求v[l]到v[r]之間的資料和,只需要用s[r]-s[l-1]就行了,兩種問題都一樣,大家可以自己試試。