社区讨论
关于这题SAM被卡掉了的一档事
P5357【模板】AC 自动机参与者 5已保存回复 6
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @locnsb8t
- 此快照首次捕获于
- 2023/10/30 16:49 2 年前
- 此快照最后确认于
- 2023/11/05 03:50 2 年前
关于这题SAM被卡掉了的一档事
请问一下诸位大佬,为什么SAM会被卡掉,而且还是内存被卡了。
SAM的理论复杂度是,在这题就是:
SAM的理论复杂度是,在这题就是:
然而却炸掉了,还是MLE,哪位大佬能来帮蒟蒻看一看,还是我对SAM的空间复杂度理解错了?
CPP#include <bits/stdc++.h>
#include <string>
#include <vector>
using namespace std;
const int N=2e6+5,M=2e5+5,INIT=1;
struct state{
int len,link;
map <char,int> nxt;
}sam[N*2];
int siz,last,cnt[N*2],tag[N],n;
string str,ade,tmp;
vector <int> son[N*2];
void sam_init(){
siz=1,last=INIT;
sam[INIT].len=0;
sam[INIT].link=0;
}
void sam_extend(char c){
int cur=++siz,p=last;
sam[cur].len=sam[last].len+1;
cnt[cur]=1;
while(p&&!sam[p].nxt.count(c)){
sam[p].nxt[c]=cur;
p=sam[p].link;
}
if(!p)sam[cur].link=INIT;
else{
int q=sam[p].nxt[c];
if(sam[q].len==sam[p].len+1){
sam[cur].link=q;
}
else{
int clone=++siz;
sam[clone]=sam[q];
sam[clone].len=sam[p].len+1;
while(p&&sam[p].nxt[c]==q){
sam[p].nxt[c]=clone;
p=sam[p].link;
}
sam[cur].link=sam[q].link=clone;
}
}
last=cur;
}
void run(int u){
for(int i=0;i<son[u].size();i++){
run(son[u][i]);
cnt[u]+=cnt[son[u][i]];
}
}
int sam_run(string s){
int len=s.size(),p=INIT;
for(int i=0;i<len;i++){
char c=s[i];
if(!sam[p].nxt[c])return 0;
else p=sam[p].nxt[c];
}
return cnt[p];
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
tag[i]=ade.size();
cin>>tmp;
ade+=tmp;
}
tag[n+1]=ade.size();
cin>>str;
sam_init();
for(int i=0;i<str.size();i++){
sam_extend(str[i]);
}
for(int i=1;i<=siz;i++){
son[sam[i].link].push_back(i);
}
run(INIT);
for(int i=1;i<=n;i++){
int p=INIT,ans=0;
for(int j=tag[i];j<tag[i+1];j++){
char c=ade[j];
if(!sam[p].nxt[c]){
ans=-1;
break;
}
p=sam[p].nxt[c];
}
if(ans==-1)printf("0\n");
else printf("%d\n",cnt[p]);
}
}
回复
共 6 条回复,欢迎继续交流。
正在加载回复...