标签:std class inf void lower 操作 分析 put long
Input
Output
Sample Input
3
1 2 3
2 1 3
Sample Output
1
Hint
分析
归并排序Code
#include <bits/stdc++.h>
const int maxn=1e5+5,Inf=2147483647;
typedef long long LL;
struct Node{
LL pos,v;
bool operator <(const Node &a)const{
return pos<a.pos;
}
}e[maxn];
LL a[maxn],b[maxn],ans=0;
int n;
void Read(){
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%lld",&e[i].pos);
for(int i=1;i<=n;++i)
scanf("%lld",&e[i].v);
std::sort(e+1,e+n+1);
for(int i=1;i<=n;++i)
a[i]=e[i].v;
}
void Print(){
for(int i=1;i<=n;++i)
printf("%lld ",a[i]);
}
void Merge(int l,int mid,int r){//合并操作
int i=l,j=mid+1,k=0;//i指向前面区间第一个元素,j指向后面区间第一元素
while(i<=mid && j<=r){//取两个序列前面的较小者
if(a[i]<=a[j])b[++k]=a[i++];
else{
ans+=mid-i+1;//a[i]~a[mid]均能和a[j]组成逆序对
b[++k]=a[j++];
}
}//跳出循环两个序列中有一个为空
while(i<=mid)//若比较完之后,第一个有序区仍有剩余
b[++k]=a[i++];
while(j<=r)//若比较完之后,第二个有序区仍有剩余
b[++k]=a[j++];
for(i=l,k=1;i<=r;++i,++k)//把合并后的排好序的序列拷贝到数组a[l,r]
a[i]=b[k];
}
void Merge_sort(int l,int r){
if(l<r){//把区间分成两部分
int mid=l+(r-l)/2;
Merge_sort(l,mid);//递归左区间
Merge_sort(mid+1,r);//递归右区间
Merge(l,mid,r);//合并左右两区间
}
}
void Solve(){
Read();
Merge_sort(1,n);
printf("%lld\n",ans);
}
int main(){
Solve();
return 0;
}
树状数组Code
#include <bits/stdc++.h>
typedef long long LL;
const LL maxn=1e5+5;
struct Node{
LL pos,v;
bool operator <(const Node &a)const{
return pos<a.pos;
}
}a[maxn];
LL b[maxn],c[maxn];
LL n;
LL lowbit(LL x){
return x & -x;
}
void Updata(LL x){
for(LL i=x;i<=n;i+=lowbit(i))
c[i]++;
}
LL Query(LL x){
LL ans=0;
for(LL i=x;i;i-=lowbit(i)){
ans+=c[i];
}
return ans;
}
void Solve(){
scanf("%lld",&n);
for(int i=1;i<=n;++i)
scanf("%lld",&a[i].pos);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i].v);
b[i]=a[i].v;
}
std::sort(a+1,a+n+1);
std::sort(b+1,b+n+1);
for(int i=1;i<=n;++i)
a[i].v=std::lower_bound(b+1,b+n+1,a[i].v)-b;
LL ans=0;
for(int i=n;i>=1;--i){
ans+=Query(a[i].v-1);
Updata(a[i].v);
}
printf("%lld\n",ans);
}
int main(){
Solve();
return 0;
}
标签:std class inf void lower 操作 分析 put long
原文地址:https://www.cnblogs.com/hbhszxyb/p/13253975.html