P1908 逆序对
P1908 逆序对
题目简述
求数列中逆序对个数
思路:
方法一:
利用树状数组,倒着来做(类似思想同P1168 中位数)
方法二:
利用归并排序,每次排序后可以利用其单调性性质直接算出答案(详细参考这个)
代码
方法一:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e5+5;
int a[N],b[N];
ll c[N];
int n;
int lowbit(int x){
return x&(-x);
}
void add(int x,int y){
for(int i=x;i<=n;i+=lowbit(i))c[i]+=y;
}
ll query(int x){
ll ans=0;
for(int i=x;i;i-=lowbit(i))ans+=c[i];
return ans;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
sort(a+1,a+1+n);
int tot=unique(a+1,a+1+n)-a-1;
for(int i=1;i<=n;i++)b[i]=lower_bound(a+1,a+1+tot,b[i])-a;
ll ans=0;
for(int i=n;i>=1;i--){
add(b[i],1);
ans+=query(b[i]-1);
}
cout<<ans<<endl;
return 0;
}
方法二:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e5+5;
int a[N],c[N];
ll ans;
int n;
void msort(int l,int r){
if(l==r)return ;
int mid=(l+r)>>1;
msort(l,mid);
msort(mid+1,r);
int b1=l,b2=mid+1;
int tmp=l;
while(b1<=mid&&b2<=r){
if(a[b1]>a[b2]){
ans+=mid-b1+1;
c[tmp++]=a[b2];
b2++;
}
else {
c[tmp++]=a[b1];
b1++;
}
}
while(b1<=mid){
c[tmp++]=a[b1];
b1++;
}
while(b2<=r){
c[tmp++]=a[b2];
b2++;
}
for(int i=l;i<=r;i++)a[i]=c[i];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
msort(1,n);
cout<<ans<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现