Description
英語老師留了N篇閱讀理解作業,但是每篇英文短文都有很多生詞需要查字典,為了節約時間,現在要做個統計,算一算某些生詞都在哪幾篇短文中出現過。
Input
第一行為整數N,表示短文篇數,其中每篇短文只含空格和小寫字母。
按下來的N行,每行描述一篇短文。每行的開頭是一個整數L,表示這篇短文由L個單片語成。接下來是L個單詞,單詞之間用一個空格分隔。
然後為一個整數M,表示要做幾次詢問。後面有M行,每行表示一個要統計的生詞。
Output
對於每個生詞輸出一行,統計其在哪幾篇短文中出現過,並按從小到大輸出短文的序號,序號不應有重複,序號之間用一個空格隔開(注意第一個序號的前面和最後一個序號的後面不應有空格)。如果該單詞一直沒出現過,則輸出一個空行。
裸的\(Trie\)樹,結果被卡空間???
搞得要開\(bitset\)。
我們對於每一個位置記錄其在哪出現過。
我們記錄\(b[x][i]\)代表當前這個單詞的結尾\(x\)是否在\(i\)行出現過。
最後查詢的時候直接列舉即可。
程式碼
#include<cstdio>
#include<bitset>
#include<iostream>
#include<algorithm>
#define R register
using namespace std;
const int gz=300001;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int ch[gz][26],idx,n,m;
bitset<1001> b[gz];
char s[31];
inline void insert(R char *s,R int x)
{
R int u=0;
for(R int i=0;s[i];i++)
{
R int v=s[i]-'a';
if(!ch[u][v])ch[u][v]=++idx;
u=ch[u][v];
}
b[u][x]=true;
}
inline void query(R char *s)
{
R int u=0;
for(R int i=0;s[i];i++)
{
R int v=s[i]-'a';
if(!ch[u][v]){goto he;}
u=ch[u][v];
}
for(R int i=1;i<=n;i++)
if(b[u][i])printf("%d ",i);
he :;
puts("");
}
int main()
{
in(n);
for(R int i=1,x;i<=n;i++)
{
in(x);
for(R int j=1;j<=x;j++)
{
scanf("%s",s);
insert(s,i);
}
}
in(m);
for(R int i=1;i<=m;i++)
{
scanf("%s",s);
query(s);
}
}