标签:nxt cnt SP8093 int 题解 void update son Sevenk
对 \(n\) 个串建广义 SAM,每个点开一棵线段树维护 parent 树子树内的所有点都被哪些串走到过。这个直接线段树合并即可。注意分裂出来的点也需要update(我也不知道为何,反正不update会WA)。
点击查看代码
const int N=5e5+13,M=5e5+13,logN=21;
int pcnt=0;
struct SegTree{int lson,rson,cnt;}t[N*logN];
#define ls t[p].lson
#define rs t[p].rson
#define mid ((l+r)>>1)
inline void refresh(int p){t[p].cnt=t[ls].cnt+t[rs].cnt;}
void update(int &p,int l,int r,int x){
if(!p) p=++pcnt;
if(l==r) return t[p].cnt=1,void();
x<=mid?update(ls,l,mid,x):update(rs,mid+1,r,x);
refresh(p);
}
void merge(int &p,int q,int l,int r){
if(!p||!q) return p|=q,void();
if(l==r) return t[p].cnt|=t[q].cnt,void();
merge(ls,t[q].lson,l,mid),merge(rs,t[q].rson,mid+1,r);
refresh(p);
}
char s[M];
int n,m,nxt[N<<1],len[N<<1],ptot=1,lastpos=1,rt[N<<1];
std::unordered_map<int,int> son[N<<1],zrzak;
std::vector<int> G[N<<1];
inline int newpos(std::unordered_map<int,int> nson,int nlen){return len[++ptot]=nlen,std::swap(son[ptot],nson),ptot;}
inline void insert(int c,int op){
int p=lastpos,u=newpos(zrzak,len[p]+1);update(rt[u],1,n,op);
while(p&&son[p].find(c)==son[p].end()) son[p][c]=u,p=nxt[p];
lastpos=u;
if(!p) return nxt[u]=1,void();
int d=son[p][c];
if(len[d]==len[p]+1) nxt[u]=d;
else{
int v=newpos(son[d],len[p]+1);update(rt[v],1,n,op);
nxt[v]=nxt[d],nxt[u]=nxt[d]=v;
while(p&&son[p][c]==d) son[p][c]=v,p=nxt[p];
}
}
void dfs(int u){for(auto v:G[u]) dfs(v),merge(rt[u],rt[v],1,n);}
int main(){
read(n),read(m);
for(int i=1;i<=n;++i){
read(s+1);
int len=strlen(s+1);
for(int j=1;j<=len;++j) insert(s[j]-'a',i);
lastpos=1;
}
for(int i=2;i<=ptot;++i) G[nxt[i]].pb(i);
dfs(1);
while(m--){
read(s+1);int len=strlen(s+1),now=1;bool flag=1;
for(int i=1;i<=len;++i){
int c=s[i]-'a';
if(son[now].find(c)==son[now].end()){flag=0;break;}
now=son[now][c];
}
if(!flag) println(0);
else println(t[rt[now]].cnt);
}
return 0;
}
标签:nxt,cnt,SP8093,int,题解,void,update,son,Sevenk 来源: https://www.cnblogs.com/winterfrost/p/sp8093-solution.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。