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;
}