字典树,注意初始化的位置~!!位置放错,永远也到不了终点了org。。。。
我是用数组模拟的字典树,这就要注意内存开多少了,,要开的不大不小刚刚好真的不容易啊。。。。
我用了val来标记是否是同一个串分解而来的,保存的是串的编号
num记录数目。
//string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last); //把[first0,last0)之间的部分替换成[first,last)之间的字符串 #include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> using namespace std; #define ll __int64 int pos; struct tt { int val,arr[27],num; tt(){ val=-1,num=0; memset(arr,-1,sizeof(arr)); } }a[500010]; //用数组模拟的字典树开的内存大小也是一个技术活,太大超内存,太小runtime errer。。 void insert(char *s,int val,int id,int d) { if(s[d]==‘\0‘)return; int t=s[d]-‘a‘; if(a[id].arr[t]==-1) a[id].arr[t]=++pos; id=a[id].arr[t]; if(a[id].val!=val) { a[id].val=val; a[id].num++; } insert(s,val,id,d+1); } int solve(char *s,int id) { int ans=0; int len=strlen(s); for(int i=0;i<len;i++) { int t=s[i]-‘a‘; if(a[id].arr[t]==-1) return 0; else id=a[id].arr[t]; } return a[id].num; } int main() { int t; pos=0;//注意初始化的位置 scanf("%d",&t); while(t--) { char s[30]; scanf("%s",s); int len=strlen(s); for(int i=0;i<len;i++) { insert(s+i,t,0,0); } } int n; scanf("%d",&n); while(n--) { char s[30]; scanf("%s",s); int ans=solve(s,0); printf("%d\n",ans); } return 0; }
HDU 2846 Repository(字典树,标记)
时间: 2024-10-10 06:14:27