题解 P3879 【[TJOI2010]阅读理解】

· · 题解

更佳的阅读体验

这篇题解求过,虽然没有tire的详细讲解,但会告诉大家数据更新后用tire怎么过,@管理大大。

这个题的数据更新了呢。所以下面所有关于tire的题解都过不了了。不过把tire讲的很详细。所以我就不多讲了。

想练习tire的我被卡的一愣愣的qaq。数组开的小了是WA#11.开成1000就是前面十个点随机MLE。

具体怎么用tire过这个题就是把标记出现的bool数组改成bitset,节省32倍空间,你,值得拥有。

就是别忘了写bitset的专用头文件。定义一个bitset后当二维数组用就好啦。

最后再丢一个博客 qwq

这里有bitset的详细用法,想学的同学了解一下。

最后是代码,除了bitset,就是普通的tire啦。

Code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <bitset>

using namespace std;

int n,m;
char s[1001];
int l;
int tot=0;
int tri[300007][26];
bitset<1001> b[500007];

inline void insert(char *s,int x){
    int rt=0;
    for(int i=0;s[i];i++){
        int v=s[i]-'a';
        if(!tri[rt][v]){
            tri[rt][v]=++tot;
        }
        rt=tri[rt][v];
    }
    b[rt][x]=1;
}

inline void query(char *s){
    int rt=0;
    for(int i=0;s[i];i++){
        int v=s[i]-'a';
        if(!tri[rt][v]){
            cout<<' '<<endl;
            return;
        }
        rt=tri[rt][v];
    }
    for(int i=1;i<=n;i++){
        if(b[rt][i]==1){
            cout<<i<<' ';
        }
    }
    cout<<endl;
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>l;
        for(int j=1;j<=l;j++){
            cin>>s;
            insert(s,i);
        }
    }
    cin>>m;
    for(int i=1;i<=m;i++){
        cin>>s;
        query(s);
    }
    return 0;
}