cf861D 字典树+时间戳
作者:互联网
好久没碰字典树之类的题了,搞起来有点生疏
/* 把所有母串的后缀加入字典树中 然后再扫一次所有母串的后缀,把后缀放到字典树中查询,找到第一个访问次数为1的结点返回即可 num在计数时,同一个母串的子串只能增加一次,所以用一个时间戳time数组来标记一下 */ #include<bits/stdc++.h> using namespace std; #define maxn 100000 char strs[maxn][20]; int n,t; struct Trie{ int nxt[maxn*10][11],num[maxn*11],time[maxn*11]; int root,L; int newnode(){ for(int i=0;i<10;i++)nxt[L][i]=-1; num[L]=0,time[L]=0; return L++; } void init(){ L=0;root=newnode(); } void insert(char buf[]){ int len=strlen(buf); int now=root; for(int i=0;i<len;i++){ if(nxt[now][buf[i]-'0']==-1) nxt[now][buf[i]-'0']=newnode(); now=nxt[now][buf[i]-'0']; if(time[now]!=t) num[now]++,time[now]=t; } } int query(char buf[]){ int len=strlen(buf); int now=root; for(int i=0;i<len;i++){ now=nxt[now][buf[i]-'0']; if(num[now]==1)return i; } return -1; } }tr; int main(){ int i; cin>>n; tr.init(); for(i=1;i<=n;i++){ t=i; cin>>strs[i]; for(int j=0;j<10;j++){ char tmp[100]={}; strcpy(tmp,strs[i]+j); tr.insert(tmp); } } for(i=1;i<=n;i++){ int l=0,r=0,Min=999; for(int j=0;j<10;j++){ char buf[100]={}; strcpy(buf,strs[i]+j); int tmp=tr.query(buf); if(tmp==-1)continue; else { if(Min>tmp){ Min=tmp; l=j,r=j+tmp; } } } for(int k=l;k<=r;k++) printf("%c",strs[i][k]); puts(""); } }
标签:11,int,后缀,时间,母串,maxn,cf861D,字典 来源: https://www.cnblogs.com/zsben991126/p/10346816.html