[浅谈] 字典树
字典树
其实是将字母放在树边上,利用空间换时间,解决前缀等问题。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+110;
int read(){
int x=0,f=1;char c=getchar();
while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int T,n,q,t[N][65],rt,newpos,cnt[N];char s[N];
int tn(char sc){
if(sc>='A' && sc<='Z')return sc-'A'+1;
if(sc>='a' && sc<='z')return sc-'a'+1+26;
if(sc>='0' && sc<='9')return sc-'0'+1+26+26;
return 0;
}
void Clear(int u){
for(int i=1;i<=26+26+10;i++){
if(t[u][i]){
Clear(t[u][i]);
t[u][i]=0;
}
}
return;
}
void solve(){
for(int i=1;i<=newpos;i++)cnt[i]=0;Clear(rt);
rt=newpos=1;
n=read(),q=read();
for(int i=1;i<=n;i++){
scanf("%s",s);int len=strlen(s),np=rt;
for(int j=0;j<len;j++){
int w=tn(s[j]);
if(t[np][w])np=t[np][w];
else np=t[np][w]=++newpos;
cnt[np]++;
}
}
for(int i=1;i<=q;i++){
scanf("%s",s);int len=strlen(s),np=rt,flag=1;
for(int j=0;j<len;j++){
int w=tn(s[j]);
if(t[np][w])np=t[np][w];
else{flag=0;break;}
}
if(flag)printf("%d\n",cnt[np]);
else printf("0\n");
}
return;
}
int main(){
T=read();
while(T--)solve();
return 0;
}
01Trie
把 \(0,1\) 放在树边上即可,因为二进制的高位特性,可以谈贪心地让高位为优,以此解决异或的一些问题。如:
P4551 最长异或路径
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+110,M=2e5+110;
int read(){
int x=0,f=1;char c=getchar();
while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int n,st[N],top,Rans;
int head[N],last[M],to[M],tot,w[M];
void Dadd(int u,int v,int t){
to[++tot]=v,w[tot]=t,last[tot]=head[u],head[u]=tot;
to[++tot]=u,w[tot]=t,last[tot]=head[v],head[v]=tot;
return;
}
void dfs(int u,int val,int fa){
st[++top]=val;
for(int i=head[u];i;i=last[i]){
int v=to[i];if(v==fa)continue;
dfs(v,val^w[i],u);
}
return;
}
int t[N*20][2],rt,poscnt;
void add(int x){
int np=rt;
for(int i=30;i>=0;i--){
bool v=(x&(1<<i));
if(t[np][v])np=t[np][v];
else np=t[np][v]=++poscnt;
}
return;
}
int query(int x){
int np=rt,ans=0;
for(int i=30;i>=0;i--){
bool v=(x&(1<<i));
if(t[np][!v]){
ans+=(1<<i);
np=t[np][!v];
}
else np=t[np][v];
}
return ans;
}
int main(){
n=read();
for(int i=1;i<n;i++){int u=read(),v=read(),t=read();Dadd(u,v,t);}
dfs(1,0,0);
rt=poscnt=1;
for(int i=1;i<=top;i++){
if(i!=1)Rans=max(Rans,query(st[i]));
add(st[i]);
}
printf("%d\n",Rans);
return 0;
}

浙公网安备 33010602011771号