樹狀陣列的幾個基本應用(更新ing)
阿新 • • 發佈:2022-04-06
一、求逆序對
最好能加入離散化,離散化的方式值得學習,開一個結構體,儲存輸入序,之後再按值大小排序,最後按輸入序賦值1-n。
#include<bits/stdc++.h> #define ll long long #define rep(i,x,n) for(int i=x;i<=n;i++) using namespace std; const int N = 1000001; int n,x,tr[N],b[N]; struct node{ int v,p; bool operator<(const node &nxt) const{ if(v==nxt.v) return p<nxt.p; return v<nxt.v; } }a[N]; int lowbit(int x) { return x&-x; } void add(int p,int x) { for(int i=p;i<=n;i+=lowbit(i)) tr[i]+=x; } int sum(int p) { int res=0; for(int i=p;i;i-=lowbit(i)) res+=tr[i]; return res; } int main() { ll ans=0; cin >> n; rep(i,1,n) { cin >> a[i].v; a[i].p=i;//p是輸入序,為啥有輸入序呢,因為直接儲存值太大了,有1e9,存不下,需要離散化,這就是離散化的關鍵一步 } sort(a+1,a+n+1); rep(i,1,n) b[a[i].p]=i;//這一步就用上了 rep(i,1,n) { ans+=sum(n)-sum(b[i]); add(b[i],1); } cout << ans; }