P5149 会议座位

首先审题,最开始我一直模拟不出来样例是怎么来的,因为我以为相邻的才可以,后面检查出来之后豁然开朗,这就是求逆序对啊。

为什么会想到求逆序对呢,因为参照样例二

A B C D E
1 2 3 4 5
B A D E C
2 1 4 5 3
对于B来说有一对(2,1) 
对于D来说有一对(4,3)
对于E来说有一对(5,3) 

并且题目已经在直白地告诉你了,原本a<b(值),但是新排的位置是a>b(位置),就是逆序对嘛。

这也是一道双倍经验题,P1908 逆序对,这道题需要离散化,因为原来的数据根本存不下,把原来的数据改为他们原来的位置即可,这道题也一样,我们多做的一步,其实就是用一个map<string,int>将名字换为位置就可以了

那么讲了这一道题的大概思路,如何求解逆序对呢?因为蒟蒻并不会归并排序,之前用的也是树状数组,但是对于其原理并不大清楚,我个人认为这一篇题解讲得比较清楚,可以去看看(应该不算抄袭什么的吧

然后就是我自己写的程序了

#include<bits/stdc++.h>
using namespace std;
map<string,int> ss;
string s;
int n;
int a[100005]; 
long long ans;

int tree[100005];
bool cmp(int x,int y){
	return a[x]<a[y];
}
int lowbit(int x){
	return x&-x;
}
void update(int x,int k){
	for(;x<=n;x+=lowbit(x)) tree[x]+=k;
}
int res=0;
int ask(int x){
	res=0;
	for(;x;x-=lowbit(x)) res+=tree[x];
	return res;
}
int main(){
	cin>>n;
	for(register int i=1;i<=n;i++){
		cin>>s;
		ss[s]=i;
	}
	for(register int i=1;i<=n;i++){
		cin>>s;
		a[i]=ss[s];
	}
	for(register int i=n;i>=1;i--){
		ans+=ask(a[i]-1);
		update(a[i],1);
	}
	cout<<ans;
	return 0;
}
原文地址:https://www.cnblogs.com/Poetic-Rain/p/13065098.html