社区讨论
刚学OI萌新想请神仙们指点一下卡空间技巧
P4595[COCI 2011/2012 #5] POPLOČAVANJE参与者 4已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mi7wmexu
- 此快照首次捕获于
- 2025/11/21 04:49 4 个月前
- 此快照最后确认于
- 2025/11/21 04:49 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct SAM
{
struct Node
{
int link;
map<int,int>ptr;
int len,endpos;
Node():link(0),len(0),endpos(0){}
Node(int link,int len):link(link),len(len),endpos(0){}
}nd[600000];
int cnt,last;
SAM():cnt(1),last(1){}
void extend(int x,int pos)
{
int now=++cnt;
nd[now].len=nd[last].len+1;
nd[now].endpos=pos;
int p=last;
while(p&&!nd[p].ptr[x])
{
nd[p].ptr[x]=now;
p=nd[p].link;
}
if(!p)
{
nd[now].link=1;
}
else
{
int q=nd[p].ptr[x];
if(nd[p].len+1==nd[q].len)
{
nd[now].link=q;
}
else
{
int clone=++cnt;
nd[clone]=Node(nd[q].link,nd[p].len+1);
nd[clone].ptr=nd[q].ptr;
while(p&&nd[p].ptr[x]==q)
{
nd[p].ptr[x]=clone;
p=nd[p].link;
}
nd[q].link=nd[now].link=clone;
}
}
last=now;
}
int topo[600001];
void gettop()
{
int *tax=new int[300001];
for(int i=1;i<=n;i++)
{
tax[i]=0;
}
for(int i=1;i<=cnt;i++)
{
tax[nd[i].len]++;
}
for(int i=1;i<=n;i++)
{
tax[i]+=tax[i-1];
}
for(int i=1;i<=cnt;i++)
{
topo[tax[nd[i].len]--]=i;
}
delete[] tax;
}
}A;
string s;
int maxx[600000];
int ans[300001];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>s;
for(int i=1;i<=n;i++)
{
A.extend(s[i-1]-'a',i);
}
A.gettop();
cin>>m;
while(m--)
{
cin>>s;
int len=s.size(),now=1;
for(int i=0;i<len;i++)
{
now=A.nd[now].ptr[s[i]-'a'];
if(!now) break;
}
if(now)
{
maxx[now]=max(maxx[now],len);
}
}
for(int i=1;i<=A.cnt;i++)
{
int x=A.topo[i];
maxx[x]=max(maxx[A.nd[x].link],maxx[x]);
if(maxx[x]&&A.nd[x].endpos)
{
ans[A.nd[x].endpos-maxx[x]+1]++;
ans[A.nd[x].endpos+1]--;
}
}
for(int i=1;i<=n;i++)
{
ans[i]+=ans[i-1];
}
int res=0;
for(int i=1;i<=n;i++)
{
res+=(ans[i]==0);
}
cout<<res<<'\n';
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...