其他分享
首页 > 其他分享> > 洛谷P1966 [NOIP2013 提高组] 火柴排队

洛谷P1966 [NOIP2013 提高组] 火柴排队

作者:互联网

题链

若要将一个排列转换成另一个排列,一次只能交换相邻两个元素,例如将 a = {4, 3, 1, 2} 变成 b = {1, 3, 2, 4},最少需要交换 a或b 几步;

新建 pa[a[i]] = i 记录排名a[i]的位置,pb[b[i]] = i 记录排名b[i]的位置,令p[pa[i]] = pb[i](相当于映射)得到的p序列求逆序数则为答案;

#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#pragma GCC optimize("O2")
using namespace std;
#define LL long long
#define ll long long
#define ULL unsigned long long
#define ls rt<<1
#define rs rt<<1|1
#define one first
#define two second
#define MS 1000009
#define INF 1e18
#define mod 99999997
#define Pi acos(-1.0)
#define Pair pair<LL,LL>
#define eps 1e-9

LL n,m,k;
LL a[MS],aa[MS],pa[MS];
LL b[MS],bb[MS],pb[MS];
LL p[MS];
LL tr[MS];

LL lowbit(LL x){
	return x&(-x);
}

void add(LL pos,LL val){
	for(;pos<=n;pos+=lowbit(pos)){
		tr[pos] += val;
		tr[pos] %= mod;
	} 
} 

LL get_sum(LL pos){
	LL ans = 0;
	for(;pos;pos-=lowbit(pos)){
		ans += tr[pos];
		ans %= mod; 
	} 
	return ans;
}

int main(){
	//ios::sync_with_stdio(false);
	cin >> n;
	
	for(int i=1;i<=n;i++){
		cin >> a[i];
		aa[i] = a[i];
	}
	for(int i=1;i<=n;i++){
		cin >> b[i];
		bb[i] = b[i];
	}
	sort(aa+1,aa+n+1);
	sort(bb+1,bb+n+1);
	for(int i=1;i<=n;i++){
		a[i] = lower_bound(aa+1,aa+n+1,a[i]) - aa;
		pa[a[i]] = i;
		b[i] = lower_bound(bb+1,bb+n+1,b[i]) - bb;
		pb[b[i]] = i;
	}
	
	for(int i=1;i<=n;i++){
		p[pa[i]] = pb[i];
	}
	LL ans = 0;
	for(int i=1;i<=n;i++){
		add(n-p[i]+1,1);
		ans += get_sum(n-p[i]);
		ans %= mod;
	}
	cout << ans << endl;
	
	

	return 0;
}

标签:aa,include,洛谷,LL,long,MS,NOIP2013,P1966,define
来源: https://www.cnblogs.com/Tecode/p/14539074.html