蒟蒻的trie树专题
POJ 3630 Phone List: 模板
///meek #include<bits/stdc++.h> using namespace std; using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define pb push_back inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar(); }return x*f; } //**************************************** const int N=500000+50; #define mod 10000007 #define inf 10000007 #define maxn 10000 char a[N]; struct Trie { int ch[N][26],sum[N]; int siz; Trie() { siz=1; mem(ch);mem(sum); } int idx(char c) {return c-'a';} void insertt(char *s) { int u=0,n=strlen(s); for(int i=0;i<n;i++) { int c=idx(s[i]); if(!ch[u][c]) { ch[u][c]=siz++; } u=ch[u][c];sum[u]++; } } int ask(char *s) { int u=0,n=strlen(s); for(int i=0;i<n;i++) { int c=idx(s[i]); if(ch[u][c]) u=ch[u][c]; else return 0; } return sum[u]; } }trie; int main() { while(gets(a)) { if(strlen(a)==0)break; trie.insertt(a); } while(scanf("%s",a)!=EOF) { cout<<trie.ask(a)<<endl; } return 0; }
HDU 1004 Let the Balloon Rise:模板
///meek #include<iostream> #include<cstdio> #include<cstring> using namespace std; using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define pb push_back inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar(); }return x*f; } //**************************************** const int N=1000+2; #define mod 10000007 #define inf 10000007 #define maxn 10000 struct Trie{ int ch[N][26],sum[N],siz=1,W=0,ansi,ans; void init() {mem(ch),mem(sum),siz=1;W=0,ansi=0;ans=-1;} int idx(char c) {return c-'a';} void insertt(char *s) { int u=0,n=strlen(s); W++; for(int i=0;i<n;i++) { int c=idx(s[i]); if(!ch[u][c]) { ch[u][c]=siz++; } u=ch[u][c],sum[u]++; if(ans<sum[u]&&i==n-1) {ans=sum[u];ansi=W;} } } }trie; int main() { char a[N][150];int n; while(scanf("%d",&n)&&n) { trie.init(); for(int i=1;i<=n;i++) { scanf("%s",a[i]); trie.insertt(a[i]); } cout<<a[trie.ansi]<<endl; } return 0; }
///meek #include<bits/stdc++.h> using namespace std; using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define pb push_back inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar(); }return x*f; } //**************************************** const int N=500000+50; #define mod 10000007 #define inf 10000007 #define maxn 10000 char a[N]; struct Trie { int ch[N][26],sum[N]; int siz; Trie() { siz=1; mem(ch);mem(sum); } int idx(char c) {return c-'a';} void insertt(char *s) { int u=0,n=strlen(s); for(int i=0;i<n;i++) { int c=idx(s[i]); if(!ch[u][c]) { ch[u][c]=siz++; } u=ch[u][c];sum[u]++; } } int ask(char *s) { int u=0,n=strlen(s); for(int i=0;i<n;i++) { int c=idx(s[i]); if(ch[u][c]) u=ch[u][c]; else return 0; } return sum[u]; } }trie; int main() { while(gets(a)) { if(strlen(a)==0)break; trie.insertt(a); } while(scanf("%s",a)!=EOF) { cout<<trie.ask(a)<<endl; } return 0; }
HDU 4825 Xor Sum : 给你n个数m个询问,每隔询问一个A,问你这n个数中与A异或值最大是多少,
将树转化成01 串的trie树,经典题型
///meek #include<iostream> #include<cstdio> #include<cstring> using namespace std; using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define pb push_back inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar(); }return x*f; } //**************************************** const int N=2000000+2; #define mod 10000007 #define inf 10000007 #define maxn 10000 struct Trie{ int ch[N][3],sum[N],siz=1,ans,W; void init(){mem(sum),mem(ch),siz=1;} void insertt(int x) { int tmp=x; int each[40],k=1;mem(each); while(x) { each[k++]=x%2; x/=2; }int u=0; for(int i=32;i>=1;i--) { int c=each[i]; if(!ch[u][c]){ ch[u][c]=siz++; } u=ch[u][c];if(i==1)sum[u]=tmp; } } int ask(int x) { int u=0;int tmp=x; int each[40],k=1;mem(each); while(x) { each[k++]=x%2; x/=2; } for(int i=32;i>=1;i--) { int g,c=each[i];if(c==1)g=0;else g=1; if(ch[u][g]) { u=ch[u][g]; } else u=ch[u][c]; if(i==1) return sum[u]; } } }trie; int main() { int T=read(),n,m,z[N]; int oo=1; while(T--) {int a[N]; trie.init(); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); trie.insertt(a[i]); } for(int i=1;i<=m;i++) { scanf("%d",&z[i]); } printf("Case #%d:\n",oo++); for(int i=1;i<=m;i++) { cout<<trie.ask(z[i])<<endl; } } return 0; }
POJ 3764 The xor-longest Path:
题意:给你一个树,及n-1条边权,问你任意一条路径上最大异或边权值是多少
题解: 我们根据异或性质,对于u->v这条路径上异或值可以转化为 XOR(0->v)^XOR(0->u)
我们先dfs出根节点到任意节点的路径异或值,于是转化成任意两个数的 异或最大值了
///meek #include<iostream> #include<cstdio> #include<cstring> using namespace std; using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define pb push_back inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar(); }return x*f; } //**************************************** const int N=2000000+200; #define mod 10000007 #define inf 10000007 #define maxn 10000 int a[N],head[N],t,n; struct ss { int to,next,va; }e[N*2]; void init() {mem(head),t=1;} void add(int u,int v,int w) {e[t].to=v;e[t].va=w;e[t].next=head[u];head[u]=t++;} void dfs(int x,int pre) { for(int i=head[x];i;i=e[i].next) { if(e[i].to==pre) continue; a[e[i].to]=e[i].va^a[x]; dfs(e[i].to,x); } } struct Trie{ int ch[N][3],sum[N],siz,ans,W; void init(){mem(sum),mem(ch),siz=1;} void insertt(int x) { int tmp=x; int each[40],k=1;mem(each); while(x) { each[k++]=x%2; x/=2; }int u=0; for(int i=32;i>=1;i--) { int c=each[i]; if(!ch[u][c]){ ch[u][c]=siz++; } u=ch[u][c];if(i==1)sum[u]=tmp; } } int ask(int x) { int u=0;int tmp=x; int each[40],k=1;mem(each); while(x) { each[k++]=x%2; x/=2; } for(int i=32;i>=1;i--) { int g,c=each[i];if(c==1)g=0;else g=1; if(ch[u][g]) { u=ch[u][g]; } else u=ch[u][c]; if(i==1) return sum[u]; } } }trie; int main() { while(scanf("%d",&n)!=EOF) { int u,v,w;init(); trie.init(); for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w),add(v,u,w); } memset(a,0,sizeof(a)); dfs(0,-1); for(int i=0;i<n;i++) { trie.insertt(a[i]); } int ans=0; for(int i=0;i<n;i++) { ans=max(ans,a[i]^trie.ask(a[i])); } cout<<ans<<endl; } return 0; }