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


posted @ 2022-03-13 15:22  Gym_nastics  阅读(15)  评论(0编辑  收藏  举报