1 基础复习
模拟STL中的set,查询一个集合中是否有字符串x,字符串x的数量,将一个字符串串x插入集合等。
用个二维数组son[N][M]来模拟二维链表,数组第一维下标表示地址,第二维下标表示字符映射,N不超过所有字符串字符个数之和、M不超过字符种类数 遍历字符串,若当前地址p的当前字符的映射k的son[p][k]已经链向另外一个地址,则p直接移到链向的地址,否则son[p][k]指向一个新地址,p移到新地址 以每个字符串的末尾字符所在位置p作为每个字符串的“索引”
起始地址p从0开始
#include <iostream>
using namespace std;
const int N = 1e5 + 5 , M = 30 ;
int ne[ N] [ M] , idx, n, cnt[ N] ;
int query ( string x)
{
int p = 0 ;
for ( int i = 0 ; x[ i] ; i++ )
{
int k = x[ i] - 'a' ;
if ( ! ne[ p] [ k] ) ne[ p] [ k] = ++ idx;
p = ne[ p] [ k] ;
}
return cnt[ p] ;
}
void add ( string x)
{
int p = 0 ;
for ( int i = 0 ; x[ i] ; i++ )
{
int k = x[ i] - 'a' ;
if ( ! ne[ p] [ k] ) ne[ p] [ k] = ++ idx;
p = ne[ p] [ k] ;
}
cnt[ p] ++ ;
}
int main ( )
{
cin >> n;
while ( n-- )
{
string x;
char op;
cin >> op;
if ( op == 'I' )
{
cin >> x;
add ( x) ;
}
else
{
cin >> x;
cout << query ( x) << endl;
}
}
return 0 ;
}
#include <iostream>
using namespace std;
const int N = 31 * 1e5 + 5 , M = 2 ;
int idx, ne[ N] [ M] , n, ans;
void add ( int x)
{
int p = 0 ;
for ( int i = 30 ; i >= 0 ; i-- )
{
int k = x >> i & 1 ;
if ( ! ne[ p] [ k] ) ne[ p] [ k] = ++ idx;
p = ne[ p] [ k] ;
}
}
int query ( int x)
{
int p = 0 , res = 0 ;
for ( int i = 30 ; i >= 0 ; i-- )
{
int k = x >> i & 1 ;
if ( ne[ p] [ ! k] )
{
res = res * 2 + ! k;
p = ne[ p] [ ! k] ;
}
else
{
res = res * 2 + k;
p = ne[ p] [ k] ;
}
}
return res;
}
int main ( )
{
cin >> n;
while ( n-- )
{
int x;
cin >> x;
add ( x) ;
ans = max ( ans, x ^ query ( x) ) ;
}
cout << ans;
return 0 ;
}
2 模板题拓展
判断是否在集合中存在一个当前串的前缀和串:创建一个bool数组f[]表示每个串的终点位置 判断当前串是否是集合中某个串的前缀和串:设一个bool变量has,只要该串在遍历过程中创建了新的节点(链向了新地址)就否
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e5 + 5 ;
int n, son[ N] [ 10 ] , idx;
bool f[ N] ;
bool insert ( string s)
{
bool has = false ;
int p = 0 ;
for ( int i = 0 ; s[ i] ; i++ )
{
int k = s[ i] - '0' ;
if ( ! son[ p] [ k] )
{
has = true ;
son[ p] [ k] = ++ idx;
}
p = son[ p] [ k] ;
if ( f[ p] ) return false ;
}
f[ p] = true ;
return has;
}
int main ( )
{
int T;
cin >> T;
while ( T-- )
{
cin >> n;
memset ( son, 0 , sizeof son) ;
memset ( f, false , sizeof f) ;
idx = 0 ;
bool res = true ;
for ( int i = 0 ; i < n; i++ )
{
string str;
cin >> str;
if ( ! insert ( str) ) res = false ;
}
if ( res) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0 ;
}