来自洛谷的模板题 题目链接
题目意思即求序列中逆序对的数目
通过ac代码来供大家学习
#include<bits/stdc++.h>
#define lowbit(x) ((x)&- (x))
using namespace std;
const int N=501000;
long long a[N],b[N];
long long tree[N];
void add(int x,int y)//添加数据
{
while(x<=N)
{
tree[x]+=y;
x+=lowbit(x);
}
}
int sum(int x)
{
int ans=0;
while(x>0)
{
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
long long n,i;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i];
}
//以下进行数据离散化,目的是为了缩短tree的空间,便于快速查找
sort(a+1,a+1+n); //先将数组排序
int cnt=unique(a+1,a+1+n)-a; //将数组去重,记录去重后数组的长度
for(i=1;i<=n;i++)
{
b[i]=lower_bound(a+1,a+1+cnt,b[i])-a; //b此时是原数组,在a数组中查看当前值排序的位置
} //赋给b数组
// 此时b数组已是离散好的数组
long long ans=0;
//以下展示两种遍历求逆序对个数的方法
for(i=n;i>=1;i--) //倒序求
{
ans+=sum(b[i]-1);//计算比tree数组中此时值比该值小的的数目有多少
add(b[i],1); //将该点加入tree数组
}
// for(i=1;i<=n;i++)//正序求
// {
// ans+=sum(N)-sum(b[i]); //计算比tree数组中此时值比该值大的的数目有多少
// add(b[i],1);
// }
cout<<ans<<'\n';
return 0;
}
洛谷 P5200 Sleepy Cow Sorting G
加更,附带一个关于树状数组的好题(链接如下)
[USACO19JAN] Sleepy Cow Sorting G - 洛谷
附我的ac代码
#include<bits/stdc++.h>
#define lowbit(x) ((x) &- (x));
using namespace std;
int n;
int tree[500009];
int a[500009];
void add (int x,int d)
{
while(x<=n)
{
tree[x]+=d;
x+=lowbit(x);
}
}
int sum(int x)
{
int ans=0;
while(x>0)
{
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
int main ()
{
int i,pos=0;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=n-1;i>=1;i--)
{
if (a[i]>a[i+1])
{
pos=i;
break;
}
}
cout<<pos<<'\n';
if (pos==0)
return 0;
for(i=pos+1;i<=n;i++)
add(a[i],1);
for(i=1;i<=pos;i++)
{
cout<<pos-i+sum(a[i])<<" ";
add(a[i],1);
}
return 0;
}
可以写这两道题巩固树状数组这个知识点哈
如有错误,虚心请教