Seating Chart
Bilbo’s birthday is coming up, and Frodo and Sam are in charge of all the party planning! They
have invited all the hobbits of Middle Earth to the party, and everyone will be sitting in a single
row at an extremely long dining table.
However, due to poor communication, Frodo and Sam have each independently put together a
seating chart for all the hobbits at the dining table. Help Frodo and Sam find out how similar their
seating charts are by counting the total number of distinct pairs of hobbits who appear in different
orders in the two charts.
Input
The input file will contain multiple test cases. Each test case begins with a single line containing
an integer N (1 ≤ N ≤ 100,000) indicating the number of hobbits. The next two lines represent
Frodo’s and Sam’s seating charts, respectively. Each seating chart is specified as a single line of
N unique alphabetical strings; the set of strings in each line are guaranteed to be identical. The
end-of-input is denoted by a line containing the number 0.
Output
For each input test case, output a single integer denoting, out of the N choose 2 distinct pairs of
hobbits, how many pairs appear in different orders in Frodo’s and Sam’s seating arrangements.
Sample Input Sample Output
3
Frodo Sam Bilbo
Sam Frodo Bilbo
5
A B C D E
B A D E C
1
3
題意:
給你n個人一開始的序列和最終序列,問你有多少對人換了位置。
題解:
對一開始給你的序列做标記,然後就是最普通的逆序對了,從後往前插,看看有多少比他小的數就好了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
map<string,int>map1;
int b[N],num[N];
int lowbit(int x)
{
return x&(-x);
}
void add(int x)
{
for(int i=x;i<N;i+=lowbit(i))
num[i]++;
}
int query(int x)
{
int ans=0;
for(int i=x;i;i-=lowbit(i))
ans+=num[i];
return ans;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n==0)
break;
map1.clear();
memset(num,0,sizeof(num));
int ct=0;
string s;
for(int i=1;i<=n;i++)
cin>>s,map1[s]=++ct;
for(int i=1;i<=n;i++)
cin>>s,b[i]=map1[s];
ll ans=0;
for(int i=n;i>=1;i--)
{
ans+=(ll)query(b[i]);
add(b[i]);
}
printf("%lld\n",ans);
}
return 0;
}