P5149 会议座位
P5149 会议座位
我感觉能用 Trie
树的题都能用 map
做,并且速度还不慢,是错觉吗
这题很简单,考虑大小写那 Trie
就是颗 52 叉树,将每个单词是第几次输入的插入到 Trie
里,然后在 Trie
里查询第二组的串,记录到一个数组里,跑逆序对即可。
/*
Knowledge : Rubbish Algorithm
Work by :Gym_nastics
Time : O(AC)
*/
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int Mod=1e9+7;
const int N=5e5+5;
int read() {
int x=0,f=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
return f?-x:x;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) print(x/10);
putchar(x%10+48);
}
struct node{int nxt[55];}Trie[N];
int en[N];int tot,a[N];
void Insert(char *s,int id){
int pos=0,len=strlen(s);
for(int i=0;i<len;i++){
int ch=s[i]-'A'+1;
if(!Trie[pos].nxt[ch]) Trie[pos].nxt[ch]=++tot;
pos=Trie[pos].nxt[ch];
}
en[pos]=id;
}
int search(char *s){
int len=strlen(s),pos=0;
for(int i=0;i<len;i++){
int ch=s[i]-'A'+1;
pos=Trie[pos].nxt[ch];
}
return en[pos];
}
char ch[N];
int n,m,Ans;
void merge(int low,int mid,int high){
int b[high-low+1]={0};
int i=low,j=mid+1,k=0;
while(i<=mid&&j<=high){
if(a[i]<=a[j]) b[++k]=a[i++];
else b[++k]=a[j++],Ans+=mid-i+1;
}
while(i<=mid) b[++k]=a[i++];
while(j<=high) b[++k]=a[j++];
for(int i=low,sc=0;i<=high;i++) a[i]=b[++sc];
}
void mergesort(int low,int high){
if(low<high){
int mid=low+high>>1;
mergesort(low,mid);
mergesort(mid+1,high);
merge(low,mid,high);
}
}
signed main() {n=read();
for(int i=1;i<=n;i++){
cin>>ch;Insert(ch,i);
}for(int i=1;i<=n;i++){
cin>>ch;a[i]=search(ch);
}
mergesort(1,n);print(Ans);
return 0;
}