(1)树状数组模板:单点修改和区间查询
P3374 【模板】树状数组 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
//lowbit函数
int lowbit(int x)
{
return x&-x;
}
//单点修改
void add(int x,int y)
{
for(int i=x;i<=n;i+=lowbit(i))
{
tr[i]+=y;
}
}
//区间查询
int query(int x)
{
int ans=0;
for(int i=x;i;i-=lowbit(i))
{
ans+=tr[i];
}
return ans;
}
(2)用树状数组求逆序对:离散化加树状数组模板。
P1908 逆序对 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<algorithm>
#include<vector>
#include<math.h>
#include<map>
#include<unordered_map>
#include<queue>
#include<stack>
#include<string>
#include<iomanip>
#include<set>
#define PII pair<int,int>
#define fi first
#define se second
#define ll long long
#define pb push_back
using namespace std;
const int inf=0x3f3f3f3f;
const int N=500005;
const int mod=1e9+7;
ll a[N],tr[N],d[N],n;
bool cmp(int x,int y)
{
if(a[x]==a[y]) return x>y;
else return a[x]>a[y];
}
ll lowbit(ll x)
{
return x&-x;
}
void add(ll x,ll y)
{
for(int i=x;i<=n;i+=lowbit(i))
{
tr[i]+=y;
}
}
ll query(ll x)
{
ll ans=0;
for(int i=x;i;i-=lowbit(i))
{
ans+=tr[i];
}
return ans;
}
void solve()
{
ll ans=0;
cin >>n;
for(int i=1;i<=n;i++)
{
cin >>a[i];
d[i]=i;
}
sort(d+1,d+1+n,cmp);
for(int i=1;i<=n;i++)
{
add(d[i],1);
ans+=query(d[i]-1);
}
cout <<ans;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t = 1;
//cin >>t;
while(t--)
{
solve();
}
return 0;
}