P3149 排序(逆序对)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3149 排序(逆序对)相关的知识,希望对你有一定的参考价值。

P3149 排序(逆序对)

​ 考虑排序对逆序对的影响,即 ≤ a k \\le a_k ak的所有数的逆序对变为 0 0 0,答案就是大于 a k a_k ak的逆序对的数,因为位置不变,所以大于 a k a_k ak的逆序对的数不受影响。

​ 故排序后,预处理逆序对后缀和与映射关系,每次询问若 c [ k ] ≥ m x c[k]\\ge mx c[k]mx ,则输出 a [ c [ k ] + 1 ] . s a[c[k]+1].s a[c[k]+1].s,否则输出 a [ m x + 1 ] . s a[mx+1].s a[mx+1].s

// Problem: P3149 排序
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3149
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// Date: 2021-07-26 08:56:47
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=3e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
int n,m,cnt;
struct BIT{
	#define lowbit(x) x&(-x)
	#define il inline
	ll s[N];
	int n;
	il void upd(int x,int v){
		while(x<=cnt){
			s[x]+=v;x+=lowbit(x);
		}return;
	}
	il ll que(int x){
		ll ans=0;
		while(x){
			ans+=s[x];x-=lowbit(x);
		}return ans;
	}
}T;
struct node{
	int v,p;
	ll s;
	bool operator<(const node &a)const{
		return v<a.v;
	}
}a[N];
int b[N],c[N];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i].v),a[i].p=i,b[i]=a[i].v;
	sort(b+1,b+n+1);
	cnt=unique(b+1,b+n+1)-b-1;
	ll ans=0;
	for(int i=n;i;i--){
		a[i].v=lower_bound(b+1,b+cnt+1,a[i].v)-b;
		a[i].s=T.que(a[i].v-1);
		ans+=a[i].s;
		T.upd(a[i].v,1);
	}
	sort(a+1,a+n+1);
	for(int i=n;i;--i){
		c[a[i].p]=i;
		a[i].s+=a[i+1].s;
	}
	printf("%lld\\n",ans);
	int mx=-1;
	while(m--){
		int k;scanf("%d",&k);
		if(c[k]>=mx) printf("%lld\\n",a[c[k]+1].s),mx=c[k];
		else printf("%lld\\n",a[mx+1].s);
	}
	return 0;
}

以上是关于P3149 排序(逆序对)的主要内容,如果未能解决你的问题,请参考以下文章

归并排序求逆序对

归并排序 逆序对

对List<Map<string,string>>排序,要求可以按照正序、逆序排序(代码写不出来可以写原理)

poj2299--归并排序求解逆序对

编程算法 - 数组中的逆序对 代码(C)

归并排序求逆序对