Tire树,hdu2846,hdu4825
放一张图来解释tire树的构成(u1s1个人感觉像是hash表)
查询有多少前缀相同字符串的模板
1 int cnt = 1; 2 int g[26 * maxn][26], vis[26 * maxn], v[26 * maxn]; 3 il void add(char *w,int id){ 4 int p = 0, l = strlen(w); 5 for (int i = 0; i < l; i++){ 6 int c = w[i] - 'a'; 7 if (!g[p][c]){ 8 g[p][c] = cnt++; 9 } 10 vis[g[p][c]]++; 11 p = g[p][c]; 12 } 13 } 14 il int query(char *w){ 15 int p = 0, l = strlen(w); 16 for (int i = 0; i < l; i++){ 17 int c = w[i] - 'a'; 18 if (!g[p][c]){ 19 return 0; 20 } 21 p = g[p][c]; 22 } 23 return vis[p]; 24 }
hdu4825
题意:
给长度为n的数组Ki(1<=i<=n),再输入m个S,在集合当中找出一个正整数 Ki ,使得 Ki 与 S 的异或结果最大
样例输入 输出:
2 Case #1:
3 2 4
3 4 5 3
1 Case #2:
5 4
4 1
4 6 5 6
3
思路:
字典树把每个数用二进制从高位到低位保存,因为高位影响较大。
寻找与S每个位都不一样的数字,但是如果哪一位没有不一样的,那只能找一样的了
#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define il inline #define it register int #define inf 0x3f3f3f3f #define lowbit(x) (x)&(-x) #define pii pair<int,int> #define mak(n,m) make_pair(n,m) #define mem(a,b) memset(a,b,sizeof(a)) #define mod 998244353 const int maxn=1e5+10; ll g[maxn*32][2],cnt, m, n, a; ll vis[maxn*32]; il void add(ll n){ ll p=0; for (it i = 32; i >= 0; i--){ int c = (n >> i) & 1; if (!g[p][c]){ g[p][c]=cnt++; } p = g[p][c]; } vis[p] = n; } il void query(ll n){ ll p = 0; for (it i = 32; i >= 0; i--){ int c = 1 - (n >> i) & 1; if (!g[p][c]){ c = 1 - c; } p = g[p][c]; } printf("%lld\n", vis[p]); } int main(){ int c=1, t; scanf("%lld",&t); while (t--){ cnt= 1; mem(vis, 0);mem(g, 0); scanf("%lld%lld",&n,&m); for (it i = 0; i < n; i++){ scanf("%lld",&a); add(a); } printf("Case #%d:\n",c++); for (it i = 0; i < m; i++){ scanf("%lld",&a); query(a); } } return 0; }
hdu2846
题意:
给n个字符串,再给m个字符串S,问S在n个字符串中是其子串
样例输入 输出
2 2
adad
dadd
1
ad
思路:
tire树,边存字符串边记录cnt出现几次。因为他要子串,所以长度较小所以可以直接暴力o(n^2),把每个子串存进去
#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define il inline #define it register int #define inf 0x3f3f3f3f #define lowbit(x) (x)&(-x) #define pii pair<int,int> #define mak(n,m) make_pair(n,m) #define mem(a,b) memset(a,b,sizeof(a)) #define mod 998244353 const int maxn=1e5+10; char s[30]; int k = 1, n, m; int g[26 * maxn][26], vis[26 * maxn], v[26 * maxn]; il void add(char *w,int id){ int p = 0, l = strlen(w); for (it i = 0; i < l; i++){ int c = w[i] - 'a'; if (!g[p][c]){ g[p][c] = k++; vis[g[p][c]]++; v[g[p][c]] = id; } p = g[p][c]; if (v[p] != id){ vis[p]++; v[p] = id; } } } il int query(char *w){ int p = 0, l = strlen(w); for (it i = 0; i < l; i++){ int c = w[i] - 'a'; if (!g[p][c]){ return 0; } p = g[p][c]; } return vis[p]; } int main(){ scanf("%d",&n); for (it i = 0; i < n; i++){ scanf("%s",&s); int l = strlen(s); for (it j = 0; j < l; j++){ add(s + j, i); } } scanf("%d",&m); for (it i = 0; i < m; i++){ scanf("%s",&s); printf("%d\n",query(s)); } return 0; }