树状数组求逆序对
作者:互联网
hdu4911为例
首先需要离散化(数据量太大)
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int lsh[1000], lshcopy[1000], sy[1000]; //lsh[n]是即将被离散化的数组,lshcopy[n]是a[n]的副本,sy[n]用于排序去重后提供离散化后的值
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&sy[i]);
lshcopy[i]=sy[i];
}
sort(sy,sy+n);//第一步排序
for(int i=0;i<n;i++)
{
cout<<'('<<sy[i]<<')';
cout<<"\n";
}
int size=unique(sy,sy+n)-sy;//unique显示去重后的个数
printf("size is : %d",size);
printf("\n");
for(int i=0;i<n;i++)
{
lsh[i]=lower_bound(sy,sy+size,lshcopy[i])-sy; //即lsh[i]为lshcopy[i]离散化后对应的值
printf("lsh is : %d",lsh[i]);
}
}
#include<cstdio>
#include<algorithm>
#include<cstring>
#define CLR(x) memset(x,0,sizeof(x))
#define ll long long int
using namespace std;
const int maxn=1e5+5;
int c[maxn]; //树状数组
int lisan[maxn]; //用来离散的存离散后的结果数组
int s[maxn]; //用来存原始状态
int n,k;
//树状数组
int lowbit(int x){ //返回值最大1e5.
return x&(-x);
}
void update(int i,int ans){
while(i <= n){
c[i] += ans;
i += lowbit(i);
}
}
int sum(int i){
int s = 0;
while(i > 0){
s += c[i];
i -= lowbit(i);
}
return s;
}
int main(){
while(~scanf("%d%d",&n,&k)){
CLR(c);
for(int i=0;i<n;i++){
scanf("%d",&s[i]);
lisan[i] = s[i];
}
sort(lisan,lisan+n);
int len=unique(lisan,lisan+n)-lisan;
ll res = 0;
for(int i=0;i<n;i++){
ll l=lower_bound(lisan,lisan+len,s[i])-lisan+1; //s[i]离散之后的值
update(l,1);
res += i+1 - sum(l);
}
if( res < k) printf("0\n");
else
printf("%lld\n",res-k);
}
}
标签:sy,树状,int,lsh,离散,数组,include,lisan,逆序 来源: https://blog.csdn.net/weixin_52466982/article/details/118999982