树状数组求逆序数对板子

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll n;
ll lowbit(ll a)
{
  return a&-a;
}
int tree[50000];
void update(ll a,ll b)
{
    while(a<=n)
    {
      tree[a]+=b;
      a+=lowbit(a);
    }
}
ll query(ll a)
{
  ll sum=0;
  while(a>=1)
  {
    sum+=tree[a];
    a-=lowbit(a);
  }
  return sum;
}
struct point
{
  ll w,pos;
}P[5000];
bool cmp(point a,point b)
{
  return a.w>b.w;
}
int main()
{

  cin>>n;
  for(int i=0;i<n;i++)
  {
    cin>>P[i].w;
    P[i].pos=i+1;
  }
  sort(P,P+n,cmp);
  ll sum=0;
  for(int i=0;i<n;i++)
  {
    update(P[i].pos,1);
    sum+=query(P[i].pos-1);
  }
  cout<<sum;
}

 

还是以刚才的序列

3 5 4 8 2 6 9

大体思路为:新建一个数组,将数组中每个元素置0

0 0 0 0 0 0 0

取数列中最大的元素,将该元素所在位置置1

0 0 0 0 0 0 1

统计该位置前放置元素的个数,为0

接着放第二大元素8,将第四个位置置1

0 0 0 1 0 0 1

统计该位置前放置元素的个数,为0

继续放第三大元素6,将第六个位置置1

0 0 0 1 0 1 1

统计该位置前放置元素的个数,为1

posted @ 2021-07-26 14:11  旅玖旅玖  阅读(41)  评论(0编辑  收藏  举报