P5149 会议座位 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目背景
话说校长最近很喜欢召开全校教职工大会,让老师们强行听他装逼
题目描述
现在校长在校园网上公布了一份座位表,nn 位老师从左到右依次排成一行。老师们都对这个座位很满意。
然而到了开会时,校长不小心把座位表打乱了,老师们很不满。老师们并不在意自己的位置变了多少,但如果有一对老师 aa 和 bb,他们原来的座位是 aa 在 bb 左边,现在变成了 aa 在 bb 右边,那么这一对老师便会贡献一单位不满值。
校长想知道这些老师的总不满值是多少。
输入格式
第一行一个正整数 nn,为 nn 位老师。
第二行有 nn 个字符串,每个字符串代表老师的名字(大小写敏感)。这一行代表原来的座位表。
第三行有 nn 个字符串,代表打乱后的座位表。
输出格式
一行,一个正整数,表示老师们的总不满值。
输入输出样例
输入 #1复制
3 Stan Kyle Kenny Kyle Stan Kenny
输出 #1复制
1
输入 #2复制
5 A B C D E B A D E C
输出 #2复制
3
说明/提示
对于 30\%30% 的数据,1\le n \le 10^31≤n≤103。
对于 100\%100% 的数据,1\le n \le 10^51≤n≤105,每位老师名字长度不超过 55,只有大小写字母并且互不相同。注意名字对大小写敏感。
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
const int MAXNODE = 500010;
const int ALPHASIZE = 52;
int ch[MAXNODE][ALPHASIZE];
int ed[MAXNODE];
struct trie{
int sz;
trie(){
sz = 1;
memset(ch,0,sizeof(ch));
}
int idx(char c){
if(c >= 'a' && c <= 'z')
return c - 'a';
else if(c >= 'A' && c <= 'Z')
return 26 + c - 'A';
}
void insert(string s, int id){
int u = 0;
for(int i = 0; i < s.size(); ++i){
int c = idx(s[i]);
if(!ch[u][c])
ch[u][c] = sz++;
u = ch[u][c];
}
ed[u] = id;
}
int search(string s){
int u = 0;
for(int i = 0; i < s.size(); ++i){
int c = idx(s[i]);
u = ch[u][c];
}
return ed[u];
}
};
int tree[MAXNODE];
int lowbit(int x)
{
return x&(-x);
}
void add(int x, int v, int n)
{
for(;x<=n; x += lowbit(x))
tree[x] += v;
}
int query(int x)
{
int ans = 0;
for(;x;x -= lowbit(x))
ans += tree[x];
return ans;
}
int main()
{
int N;
trie t;
string s;
cin >> N;
memset(tree,0,sizeof(tree));
for(int i = 1; i <= N; ++i){
cin >> s;
t.insert(s, i);
}
long long ans = 0;
for(int i = 1; i <= N; ++i){
cin >> s;
int id = t.search(s);
add(id,1,N);
ans += i - query(id);
}
cout << ans << endl;
return 0;
}