2.树状数组是什么?一句话,树状数组有其特定的作用,其用途较窄,它能做的线段树都能做!
3. 求区间查询和单点更新tree[1] = a1
tree[2] = tree[1] + a2;
tree[3] = a3;
tree[4] = tree[3] + tree[2] + a4 = a1 + a2 + a3 + a4;
tree[5] = a5;
tree[6] = tree[5] + a6 = a5 + a6;e
…
lowbit : 用于取出最低位的1
int lowbit(int x){
return x & (-x);
}
单点更新
void update(int x,int val){
while(x<=n){
c[x] += val;
x += lowbit(x);
}
}
区间查询(前缀和)
int getSum(int x){
int ans = 0;
while(x){
ans += c[x];
x -= lowbit(x);
}
return ans;
}
#include4. 求逆序对#include #include // 树状数组 using namespace std; // 原数组 树状数组 int a[100010],c[100010]; int n,m; int lowbit(int x){ return x & (-x); } // 求前缀和 int getSum(int x){ int ans = 0; while(x){ ans += c[x]; x -= lowbit(x); } return ans; } void update(int x,int val){ while(x<=n){ c[x] += val; x += lowbit(x); } } int main() { while(scanf("%d",&n)!=EOF){ memset(a,0,sizeof a); memset(c,0,sizeof c); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); update(i,a[i]); } int ans = getSum(n); cout << ans << endl; } return 0; }
#include#include #include #include using namespace std; typedef pair PII; const int N = 100100; int n; int tree[N],b[N]; // b[n]存储离散化且排序后原始 pos PII a[N]; // 输入 a[i].fi 存储值,a[i].se 存储 pos // 取出二进制下第一个1及以后的数 int lowbit(int x){ return x & (-x); } // 更新点 void update(int x,int val){ while(x<=n){ tree[x] += val; x += lowbit(x); } } // 前缀和 int getSum(int x){ int ans = 0; while(x){ ans += tree[x]; x -= lowbit(x); } return ans; } int main() { memset(tree,0,sizeof tree); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i].first); a[i].second = i; } sort(a+1,a+n+1); int pos = 1; for(int i=1;i<=n;i++){ if(a[i].first!=a[i-1].first && i!=1) pos++; b[a[i].second] = pos; } // 求逆序对数量. int sum = 0; for(int i=1;i<=n;i++){ update(b[i],1); sum += (i - getSum(b[i])); } cout << sum << endl; return 0; }
求逆序对(贪心+树状数组)
Array Optimization by Deque



