主要用途:
- 检索字符串
- 求异或类型
- 维护异或极值
- 维护异或和
模板
struct trie {
int nex[100000][26], cnt;
bool exist[100000]; // 该结点结尾的字符串是否存在
void insert(char *s, int l) { // 插入字符串
int p = 0;
for (int i = 0; i < l; i++) {
int c = s[i] - 'a';
if (!nex[p][c]) nex[p][c] = ++cnt; // 如果没有,就添加结点
p = nex[p][c];
}
exist[p] = 1;
}
bool find(char *s, int l) { // 查找字符串
int p = 0;
for (int i = 0; i < l; i++) {
int c = s[i] - 'a';
if (!nex[p][c]) return 0;
p = nex[p][c];
}
return exist[p];
}
};
从oi-wiki 上的模板贺过来的(其实是懒得自己打(逃
例题:于是他错误的点名开始了
只要对于出现的名字建 Trie ,再使用 Trie 查询字符串是否存在即可。
code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
struct node{int sn[27],num;}a[N];
int cnt,n,m,res;char ch[55];
void build()//建 Trie
{
int l=strlen(ch),p=0;
for(int i=0;i<l;i++)
{
if(!a[p].sn[ch[i]-'a']) a[p].sn[ch[i]-'a']=++cnt;
p=a[p].sn[ch[i]-'a'];
}
}
int qry()//查找字符串
{
int l=strlen(ch),p=0;
for(int i=0;i<l;i++)
{
if(!a[p].sn[ch[i]-'a']) return 0;
p=a[p].sn[ch[i]-'a'];
}
return ++a[p].num;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%s",ch),build();
scanf("%d",&m);
while(m--)
{
scanf("%s",ch);res=qry();
if(res==0) puts("WRONG");
else if(res==1) puts("OK");
else if(res>=2) puts("REPEAT");
}
return 0;
}
两两异或中的最大值
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,T,num,ans,x[N];string tp;
struct node{
int ch[3],sum;bool fla;
void clr(){memset(ch,0,sizeof ch);sum=fla=0;}
}t[N<<2];
void inst(string s)
{
int sz=s.size(),a=0;
for(int i=0;i<sz;i++)
{
int b=s[i]-'0';
if(!t[a].ch[b]) t[a].ch[b]=++num;
t[a].sum++,a=t[a].ch[b];
}
}
int fnd(string s)//查找最大值
//在 Trie 上用贪心的思想尽量往于当前相反的节点跑
//如果没有就只能走原来的数位,根据异或的运算法则,可以得到两个数异或的最大值的
//
{
int sz=s.size(),a=0,res=0,nu=(INT_MAX)/2+1;
for(int i=0;i<sz;i++)
{
int b=(s[i]-'0')^1;
if(!t[a].ch[b]) b^=1;else res+=nu;
a=t[a].ch[b];nu/=2;
}return res;
}
string inbit(int x)//把每个数转化为二进制存入 Trie 中
//注意转化时倒着存储,方便更新答案
{
string res="";
while(x) res+=(x%2)+'0',x>>=1;
while(res.size()!=31) res+='0';
reverse(res.begin(),res.end());
return res;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&x[i]),tp=inbit(x[i]),inst(tp);
for(int i=1;i<=n;i++) ans=max(ans,fnd(inbit(x[i])));
printf("%d",ans);
return 0;
}
两个不相交区间的异或值相加最大值
咕咕咕ing
\(\texttt{End.}\)