P5149 会议座位
题目
思路
最近看了看Trie数组,这个东西其实还蛮快的,就是容易爆内存V_V,然后再打一个求逆序对的板子就好了。
代码
注意开long long!
#include <bits/stdc++.h>
using namespace std;
const int N = 5 * 1e5 + 10;
int son[N][60], cnt[N], idx;
string tcher[N], tmp[N];
void insert(string s, int k) {
int pos = 0;
for (int i = 0; s[i]; ++i) {
int t = s[i] - 'A';
if (!son[pos][t])
son[pos][t] = ++idx;
pos = son[pos][t];
}
cnt[pos] = k;//记录下当前的位置
}
int query(string s) {
int pos = 0;
for (int i = 0; s[i]; ++ i) {
int t = s[i] - 'A';
if (!son[pos][t])
return -1;
pos = son[pos][t];
}
return cnt[pos];
}
long long merge_sort(int l, int r) {
if (l >= r)
return 0;
long long res = 0;
int mid = (l + r) >> 1;
res = merge_sort(l, mid) + merge_sort(mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid and j <= r) {
if (query(tcher[i]) <= query(tcher[j]))
tmp[k++] = tcher[i++];
else {
tmp[k++] = tcher[j++];
res += mid - i + 1;
}
}
while (i <= mid)
tmp[k++] = tcher[i++];
while (j <= r)
tmp[k++] = tcher[j++];
for (int i = l, j = 0; i <= r; ++i, ++j)
tcher[i] = tmp[j];
return res;
}
int main() {
cin.tie(0);
ios::sync_with_stdio(false);
int n;
cin >> n;
for (int i = 0; i < n ; ++ i) {
string temp;
cin >> temp;
insert(temp, i);
//temp是插入的名字 i是对应的编号
}
for (int i = 0; i < n; ++ i) {
cin >> tcher[i];
}
cout << merge_sort(0, n - 1);
}