P2922 秘密消息Secret Message
这道题还是,先将
插入很好办,我们现在来讨论查询操作。我们记
那么会出现三种情况:
1.
2.
3.
但是,
那么,一道难蓝题就被我们解决了,附上代码:
#include <cstdio>
#include <cstring>
const int MAXN = 500000;
int n,m,len;
int Trie[ MAXN + 5 ][ 2 ] , cnt;
int tot[ MAXN + 5 ] , fin[ MAXN + 5 ];
void Insert( char *str , int len ) {
int u = 0;
for( int i = 0 ; i < len ; i ++ ) {
int num = str[ i ] - '0';
if( !Trie[ u ][ num ] )
Trie[ u ][ num ] = ++ cnt;
u = Trie[ u ][ num ];
tot[ u ] ++;
}
fin[ u ] ++;
}
int Find( char *str , int len ) {
int u = 0 , Ans = 0;
for( int i = 0 ; i < len ; i ++ ) {
int num = str[ i ] -'0';
if( !Trie[ u ][ num ] )
return Ans;
u = Trie[ u ][ num ];
Ans += fin[ u ];
}
return Ans - fin[ u ] + tot[ u ];
}
int s1;
char s[ 10005 ];
int main( ) {
scanf("%d %d",&m,&n);
for( int i = 1 ; i <= m ; i ++ ) {
scanf("%d",&len);
for( int j = 0 ; j < len ; j ++ ) {
scanf("%d",&s1);
s[ j ] = s1 + '0';
}
Insert( s , len );
}
for( int i = 1 ; i <= n ; i ++ ) {
scanf("%d",&len);
for( int j = 0 ; j < len ; j ++ ) {
scanf("%d",&s1);
s[ j ] = s1 + '0';
}
printf("%d\n",Find( s , len ));
}
return 0;
}