(17/34)AC自动机/后缀数组/后缀自动机(施工中)
快补题别再摸鱼了(17/34)
1.AC自动机
#define maxnode 1000010
#define maxsize 26
struct ahocT{
int ch[maxnode][maxsize];
int e[maxnode],fail[maxnode];
int sz;
void init(){
sz=;memset(ch[],,sizeof(ch[]));memset(e,,sizeof(e));return;
}
int idx(char c) {return c-'a';}
void insert(char *x){
int u=,len=strlen(x);
FOR(i,,len){
int c=idx(x[i]);
if(!ch[u][c]){
memset(ch[sz],,sizeof(ch[sz]));
ch[u][c]=sz++;
}
u=ch[u][c];
}
e[u]++;
return;
}
void build(){
int u;
queue<int> q;
memset(fail,,sizeof(fail));
FOR(i,,)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty()){
u=q.front();q.pop();
FOR(i,,){
if(ch[u][i]) {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
else ch[u][i]=ch[fail[u]][i];
}
}
return;
}
int query(char *x){
int ans=,c=,len=strlen(x);
FOR(i,,len){
c=ch[c][idx(x[i])];
for(int j=c;j&&~e[j];j=fail[j]) ans+=e[j],e[j]=-;
}
return ans;
}
}
非拓扑序后缀链接ac自动机
模板写法及变式(待更新)
ac自动机的主要考察方向:DP 矩阵转移 图论
HDU 2222
多模式串匹配 模板题
//#define LOCAL
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
#define X_mem(x,y,z) (X_mem[x][y][z] ? X_mem[x][y][z] :X_mem[x][y][z]=mem(x,y,z))
// X_INIT=0 mem_Macro
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define FOR(i,j,k) for(int i=j;i<k;i+=1)
#define FORD(i,j,k) for(int i=j;i>k;i-=1)
#define uLL unsigned long long
#define LL long long
#define SZ(x) int(x.size())
#define pb push_back
#define maxnode 1000010
#define maxsize 26
int n;
char x[];
int ch[maxnode][maxsize];
int e[maxnode],fail[maxnode];
int sz;
void init(){
sz=;/*memset(ch[0],0,sizeof(ch[0]));memset(e,0,sizeof(e));*/return;
}
int idx(char c) {return c-'a';}
void insert(char *x){
int u=,len=strlen(x);
FOR(i,,len){
int c=idx(x[i]);
if(!ch[u][c]){
/*memset(ch[sz],0,sizeof(ch[sz]));*/
ch[u][c]=sz++;
}
u=ch[u][c];
}
e[u]++;
return;
}
void build(){
int u;
queue<int> q;
//memset(fail,0,sizeof(fail));
FOR(i,,)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty()){
u=q.front();q.pop();
FOR(i,,){
if(ch[u][i]) {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
else ch[u][i]=ch[fail[u]][i];
}
}
return;
}
int query(char *x){
int ans=,c=,len=strlen(x);
FOR(i,,len){
c=ch[c][idx(x[i])];
for(int j=c;j&&~e[j];j=fail[j]) ans+=e[j],e[j]=-;
}
return ans;
}
int main(){
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
//ahocT tr;
int t;
scanf("%d",&t);
FOR(i,,t){
init();
sz=;
scanf("%d",&n);
FOR(i,,n){
scanf("%s",x);
insert(x);
}
build();
scanf("%s",x);
printf("%d\n",query(x));
}
//system("pause");
#ifdef LOCAL
fclose(stdin);
fclose(stdout);
#endif
return ;
}
ac代码
HDU 2896
多模式串匹配统计,多模板串set处理
//#define LOCAL
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
#define X_mem(x,y,z) (X_mem[x][y][z] ? X_mem[x][y][z] :X_mem[x][y][z]=mem(x,y,z))
// X_INIT=0 mem_Macro
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define FOR(i,j,k) for(int i=j;i<k;i+=1)
#define FORD(i,j,k) for(int i=j;i>k;i-=1)
#define uLL unsigned long long
#define LL long long
#define SZ(x) int(x.size())
#define pb push_back
#define maxnode 100010
#define maxsize 130
int l,n;
char x[];
struct ahocT{
int ch[maxnode][maxsize];
int e[maxnode],fail[maxnode],vis[maxnode];
int sz;
void init(){
sz=;memset(ch[],,sizeof(ch[]));memset(e,,sizeof(e));return;
}
int idx(char c) {return (int)c;}
void insert(char *x,int num){
int u=,len=strlen(x);
FOR(i,,len){
int c=idx(x[i]);
if(!ch[u][c]){
memset(ch[sz],,sizeof(ch[sz]));
ch[u][c]=sz++;
}
u=ch[u][c];
}
e[u]=num;
return;
}
void build(){
int u;
queue<int> q;
memset(fail,,sizeof(fail));
FOR(i,,)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty()){
u=q.front();q.pop();
FOR(i,,){
if(ch[u][i]) {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
else ch[u][i]=ch[fail[u]][i];
}
}
return;
}
int query(char *x,int ii){
int ans=,c=,len=strlen(x);
memset(vis,,sizeof(vis));
FOR(i,,len){
c=ch[c][idx(x[i])];
for(int j=c;j&&~e[j];j=fail[j]) vis[e[j]]++,ans+=e[j];
}
if(ans) {printf("web %d:",ii);
FOR(j,,sz)
if(e[j]) if(vis[e[j]]) printf(" %d",e[j]);
printf("\n");return ;} else return ;
}
};
ahocT xx;
int main(){
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
scanf("%d",&n);
xx.init();
FOR(i,,n+){
scanf("%s",x);
xx.insert(x,i);
}
xx.build();
scanf("%d",&n);
int l=;
FOR(i,,n+){
scanf("%s",x);
l+=xx.query(x,i); }
printf("total: %d\n",l);
//system("pause");
#ifdef LOCAL
fclose(stdin);
fclose(stdout);
#endif
return ;
}
ac代码
HDU 3065
多模式串匹配统计次数
为防止多个模式串重复,一般分配map映射
//#define LOCAL
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
#define X_mem(x,y,z) (X_mem[x][y][z] ? X_mem[x][y][z] :X_mem[x][y][z]=mem(x,y,z))
// X_INIT=0 mem_Macro
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define FOR(i,j,k) for(int i=j;i<k;i+=1)
#define FORD(i,j,k) for(int i=j;i>k;i-=1)
#define uLL unsigned long long
#define LL long long
#define SZ(x) int(x.size())
#define pb push_back
#define maxnode 100010
#define maxsize 130
int l,n;
char lx[][];
char xxx[];
struct ahocT{
int ch[maxnode][maxsize];
int e[maxnode],fail[maxnode],vis[maxnode];
int idxx[maxnode];
int sz;
void init(){
sz=;memset(ch[],,sizeof(ch[]));memset(e,,sizeof(e));return;
}
int idx(char c) {return (int)c;}
void insert(char *x,int num){
int u=,len=strlen(x);
FOR(i,,len){
int c=idx(x[i]);
if(!ch[u][c]){
memset(ch[sz],,sizeof(ch[sz]));
ch[u][c]=sz++;
}
u=ch[u][c];
}
e[u]=num;idxx[num]=u;
return;
}
void build(){
int u;
queue<int> q;
memset(fail,,sizeof(fail));
FOR(i,,)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty()){
u=q.front();q.pop();
FOR(i,,){
if(ch[u][i]) {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
else ch[u][i]=ch[fail[u]][i];
}
}
return;
}
void query(char *x){
int ans=,c=,len=strlen(x);
memset(vis,,sizeof(vis));
FOR(i,,len){
c=ch[c][idx(x[i])];
for(int j=c;j&&~e[j];j=fail[j]) vis[j]++,ans+=e[j];
}
//printf("web %d:",ii);
FOR(j,,n+){
if(vis[idxx[j]])
printf("%s: %d\n",lx[j],vis[idxx[j]]);
}
//if(e[j]) if(vis[e[j]]) printf(" %d",e[j]);
//printf("\n");return 1;} else return 0;
return;
}
};
ahocT xx;
int main(){
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
while(scanf("%d",&n)!=EOF){
xx.init();
FOR(i,,n+){
scanf("%s",lx[i]);
xx.insert(lx[i],i);
}
xx.build();
//scanf("%d",&n);
//int l=0;
//FOR(i,1,n+1){
scanf("%s",xxx);
xx.query(xxx);
//cout<<xxx;
//}
//printf("total: %d\n",l);
}
//system("pause");
#ifdef LOCAL
fclose(stdin);
fclose(stdout);
#endif
return ;
}
ac代码
ZOJ 3430
base64转码+多模式串匹配统计
//#define LOCAL
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
#define X_mem(x,y,z) (X_mem[x][y][z] ? X_mem[x][y][z] :X_mem[x][y][z]=mem(x,y,z))
// X_INIT=0 mem_Macro
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define FOR(i,j,k) for(int i=j;i<k;i+=1)
#define FORD(i,j,k) for(int i=j;i>k;i-=1)
#define uLL unsigned long long
#define LL long long
#define SZ(x) int(x.size())
#define pb push_back
#define maxnode 50010
#define maxsize 256
char x[];
int xx[];
int id(char c) {
if(c >= 'A' && c <= 'Z') return c - 'A';
else if(c >= 'a' && c <= 'z') return c - 'a' + ;
else if(c >= '' && c <= '') return c - '' + ;
else if(c == '+') return ;
else return ;
}
struct ahocT{
int ch[maxnode][maxsize];
int e[maxnode],fail[maxnode];
int vis[maxnode];
int sz;
void init(){
sz=;memset(ch[],,sizeof(ch[]));memset(e,,sizeof(e));return;
}
int idx(int c) {return c;}
void insert(int *x,int len){
int u=;//,len=strlen(x);
FOR(i,,len){
int c=idx(x[i]);
if(!ch[u][c]){
memset(ch[sz],,sizeof(ch[sz]));
ch[u][c]=sz++;
}
u=ch[u][c];
}
e[u]++;
return;
}
void build(){
int u;
queue<int> q;
memset(fail,,sizeof(fail));
FOR(i,,)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty()){
u=q.front();q.pop();
FOR(i,,){
if(ch[u][i]) {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
else ch[u][i]=ch[fail[u]][i];
}
}
return;
}
int query(int *x,int len){
int ans=,c=;//len=strlen(x);
memset(vis,,sizeof(vis));
FOR(i,,len){
c=ch[c][idx(x[i])];
for(int j=c;j&&~e[j];j=fail[j]) if(vis[j]==) {ans+=e[j],vis[j]=;}
//{ans+=e[j],e[j]=-1;}
}
return ans;
}
} tt;
int main(){
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
int n,m;
while(scanf("%d",&n)!=EOF){
tt.init();
//cout<<"**";
FOR(i,,n){
scanf("%s",x);
int len=strlen(x);
int cnt=;
while(x[len-]=='=') len--;
for(int j=;j<len;j+=){
xx[cnt++]=(id (x[j])<<|id(x[j+])>>);//6 2
if(j+<len) xx[cnt++]=((id(x[j+])&0x0f)<<)|id(x[j+])>>;//4 4
if(j+<len) xx[cnt++]=((id(x[j+])&0x03)<<)|id(x[j+]);//2 6
}
/* FOR(j,0,cnt)
cout<<xx[j]<<' ';
cout<<' '<<endl;*/
tt.insert(xx,cnt);
}
tt.build();
scanf("%d",&m);
FOR(i,,m){
scanf("%s",x);
int len=strlen(x);
int cnt=;
while(x[len-]=='=') len--;
for(int j=;j<len;j+=){
xx[cnt++]=(id(x[j])<<|id(x[j+])>>);//6 2
if(j+<len) xx[cnt++]=((id(x[j+])&0x0f)<<)|id(x[j+])>>;//4 4
if(j+<len) xx[cnt++]=((id(x[j+])&0x03)<<)|id(x[j+]);//2 6
}
/* FOR(j,0,cnt)
cout<<xx[j]<<' ';
cout<<' '<<endl;*/
printf("%d\n",tt.query(xx,cnt));
}
printf("\n");
}
//system("pause");
#ifdef LOCAL
fclose(stdin);
fclose(stdout);
#endif
return ;
}
ac代码
POJ 2778
求不出现模式串的定长构造串个数
矩阵快速幂转移fail矩阵 求sigma(fail[0][i])
//#define LOCAL
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
#define X_mem(x,y,z) (X_mem[x][y][z] ? X_mem[x][y][z] :X_mem[x][y][z]=mem(x,y,z))
// X_INIT=0 mem_Macro
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define FOR(i,j,k) for(int i=j;i<k;i+=1)
#define FORD(i,j,k) for(int i=j;i>k;i-=1)
#define uLL unsigned long long
#define LL long long
#define SZ(x) int(x.size())
#define pb push_back
#define maxnode 110
#define maxsize 26
char x[];
LL dp[][];
map<char,int> id;
struct ahocT{
int ch[maxnode][maxsize];
int e[maxnode],fail[maxnode];
int sz;
void init(){
sz=;memset(ch[],,sizeof(ch[]));memset(e,,sizeof(e));return;
}
int idx(char c) {return id[c];}
void insert(char *x){
int u=,len=strlen(x);
FOR(i,,len){
int c=idx(x[i]);
if(!ch[u][c]){
memset(ch[sz],,sizeof(ch[sz]));
ch[u][c]=++sz;
}
u=ch[u][c];
}
e[u]++;
return;
}
void build(){
int u;
queue<int> q;
memset(fail,,sizeof(fail));
FOR(i,,)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty()){
u=q.front();q.pop();
FOR(i,,){
if(ch[u][i]) {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
if(e[fail[ch[u][i]]]) e[ch[u][i]]=;
}
else ch[u][i]=ch[fail[u]][i];
}
}
return;
}
int query(char *x){
int ans=,c=,len=strlen(x);
FOR(i,,len){
c=ch[c][idx(x[i])];
for(int j=c;j&&~e[j];j=fail[j]) ans+=e[j],e[j]=-;
}
return ans;
}
}tt;
/*()
void(LL *a,int len,int cc){
LL xx[len+1][len+1],tmp[len+1][len+1],ans[len+1][len+1];
int c=cc;
//memset(xx,0,sizeof(xx))拢禄
FOR(i,0,len)
FOR(j,0,len)
xx[i][j]=a[i][j];
while(c){
if(c&1){
FOR(i,0,len)
FOR(j,0,len)
FOR(k,0,len)
tmp[i][j]+=ans[i][k]*a[k][j];
FOR(i,0,len)
FOR(j,0,len)
ans[i][j]=tmp[i][j];
}
FOR(i,0,len)
FOR(j,0,len)
FOR(k,0,len)
tmp[i][j]+=xx[i][k]*xx[k][j];
FOR(i,0,len)
FOR(j,0,len)
xx[i][j]=tmp[i][j];
c/=2;
}
int anss=0;
FOR(i,0,len)
anss+=ans[0][i];
printf("%lld\n",anss);
return;
}*/
int main(){
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
id['A']=;
id['T']=;
id['G']=;
id['C']=;
int m,n;
scanf("%d%d",&m,&n);
FOR(i,,m){
scanf("%s",x);
tt.insert(x);
}
tt.build();
//cout<<tt.sz;
int len=tt.sz+;
FOR(i,,tt.sz+){
if(!tt.e[i])
FOR(j,,)
if(!tt.e[tt.ch[i][j]])dp[i][tt.ch[i][j]]++;
}
/*FOR(i,0,tt.sz+1){
FOR(j,0,tt.sz+1)
cout<<dp[i][j];
cout<<endl;
}*/
//q_pow(dp,len,m);
LL xx[][],tmp[][],ans[][];
int c=n;
memset(ans,,sizeof(ans));
FOR(i,,len)
FOR(j,,len)
xx[i][j]=dp[i][j];
FOR(i,,len)
ans[i][i]=;
while(c){
// cout<<c<<endl;
if(c&){ memset(tmp,,sizeof(tmp));
FOR(i,,len)
FOR(j,,len)
FOR(k,,len)
tmp[i][j]+=xx[i][k]*ans[k][j],tmp[i][j]%=;
FOR(i,,len)
FOR(j,,len)
ans[i][j]=tmp[i][j];
}
memset(tmp,,sizeof(tmp));
FOR(i,,len)
FOR(j,,len)
FOR(k,,len)
tmp[i][j]+=xx[i][k]*xx[k][j],tmp[i][j]%=;
FOR(i,,len)
FOR(j,,len)
xx[i][j]=tmp[i][j];
c>>=;
/* FOR(i,0,len){
FOR(j,0,len)
cout<<ans[i][j];
cout<<endl;} */}
LL anss=;
FOR(i,,len)
anss+=ans[][i];
printf("%lld\n",anss%);
//system("pause");
#ifdef LOCAL
fclose(stdin);
fclose(stdout);
#endif
return ;
}
ac代码
HDU 2243
求出现模式串的不定长构造串个数
构造矩阵A:【fail E】和B:【26 1】
【0 E】 【0 1】
矩阵快速幂转移后求B左上与A右上第一行simga之差
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
#define X_mem(x,y,z) (X_mem[x][y][z] ? X_mem[x][y][z] :X_mem[x][y][z]=mem(x,y,z))
// X_INIT=0 mem_Macro
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define FOR(i,j,k) for(int i=j;i<k;i+=1)
#define FORD(i,j,k) for(int i=j;i>k;i-=1)
#define uLL unsigned long long
#define LL long long
#define SZ(x) int(x.size())
#define pb push_back
#define maxnode 110
#define maxsize 26
#define N 100
struct Mat{
uLL mat[N][N];
};
Mat operator *(Mat x,Mat y){
Mat c;
memset(c.mat,,sizeof(c.mat));
FOR(k,,N)
FOR(i,,N){
if(x.mat[i][k]<=) continue;
FOR(j,,N){
if(y.mat[k][j]<=) continue;
c.mat[i][j]+=x.mat[i][k]*y.mat[k][j];
}
}
return c;
}
char x[];
uLL dp[][];
map<char,int> id; struct ahocT{
int ch[maxnode][maxsize];
int e[maxnode],fail[maxnode];
int sz;
void init(){
sz=;memset(ch[],,sizeof(ch[]));memset(e,,sizeof(e));return;
}
int idx(char c) {return c-'a';}
void insert(char *x){
int u=,len=strlen(x);
FOR(i,,len){
int c=idx(x[i]);
if(!ch[u][c]){
memset(ch[sz],,sizeof(ch[sz]));
ch[u][c]=sz++;
}
u=ch[u][c];
}
e[u]++;
return;
}
void build(){
int u;
queue<int> q;
memset(fail,,sizeof(fail));
FOR(i,,)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty()){
u=q.front();q.pop();
FOR(i,,){
if(ch[u][i]) {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
if(e[fail[ch[u][i]]]) e[ch[u][i]]=;
}
else ch[u][i]=ch[fail[u]][i];
}
}
return;
}
int query(char *x){
int ans=,c=,len=strlen(x);
FOR(i,,len){
c=ch[c][idx(x[i])];
for(int j=c;j&&~e[j];j=fail[j]) ans+=e[j],e[j]=-;
}
return ans;
}
}tt;
Mat qpow(Mat x,int le){
Mat res;
memset(res.mat,,sizeof(res.mat));
int cc=le;
FOR(i,,N)
res.mat[i][i]=;
while(cc){
if(cc&) res=res*x;
x=x*x;
cc>>=;
}
return res;
}
int main(){
int m,n; while(scanf("%d%d",&m,&n)!=EOF){
tt.init();
FOR(i,,m){
scanf("%s",x);
tt.insert(x);
}
tt.build();
Mat dp;
memset(dp.mat,,sizeof(dp.mat));
FOR(i,,tt.sz){
if(tt.e[i]) continue;
FOR(j,,)
if(tt.e[tt.ch[i][j]]==)dp.mat[i][tt.ch[i][j]]++;
}
FOR(i,tt.sz,*tt.sz)
dp.mat[i-tt.sz][i]=;
FOR(i,tt.sz,*tt.sz)
dp.mat[i][i]=;/*
FOR(i,0,tt.sz)
cout<<tt.e[i];
cout<<tt.sz<<endl; FOR(i,0,2*tt.sz){
FOR(j,0,2*tt.sz)
cout<<dp.mat[i][j]<<' ';
cout<<endl;
}*/dp=qpow(dp,n);
uLL ans=;
FOR(i,,*tt.sz)
ans+=dp.mat[][i];
ans--;
//LL ans=dp.mat[0][tt.sz+1]-1;
Mat p;
memset(p.mat,,sizeof(p.mat));
p.mat[][]=;p.mat[][]=;p.mat[][]=;
p=qpow(p,n);
uLL ans2=p.mat[][]+p.mat[][];
ans2--;
cout<<ans2-ans<<endl;
}
return ;
}
ac代码
POJ 1625
求不出现模式串的定长构造串个数的高精度大数
加上大数模板
未写题:
HDU 2825
HDU 2296
HDU 2457
ZOJ 3228
HDU 3341
HDU 3247
HDU 4758
HDU 4511
2.后缀数组
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream> using namespace std; const int N = ; char s[N];
int n, w, sa[N], rk[N << ], oldrk[N << ];
// 为了防止访问 rk[i+w] 导致数组越界,开两倍数组。
// 当然也可以在访问前判断是否越界,但直接开两倍数组方便一些。 int main() {
int i, p; scanf("%s", s + );
n = strlen(s + );
for (i = ; i <= n; ++i) rk[i] = s[i]; for (w = ; w < n; w <<= ) {
for (i = ; i <= n; ++i) sa[i] = i;
sort(sa + , sa + n + , [](int x, int y) {
return rk[x] == rk[y] ? rk[x + w] < rk[y + w] : rk[x] < rk[y];
}); // 这里用到了 lambda
memcpy(oldrk, rk, sizeof(rk));
// 由于计算 rk 的时候原来的 rk 会被覆盖,要先复制一份
for (p = , i = ; i <= n; ++i) {
if (oldrk[sa[i]] == oldrk[sa[i - ]] &&
oldrk[sa[i] + w] == oldrk[sa[i - ] + w]) {
rk[sa[i]] = p;
} else {
rk[sa[i]] = ++p;
} // 若两个子串相同,它们对应的 rk 也需要相同,所以要去重
}
} for (i = ; i <= n; ++i) printf("%d ", sa[i]); return ;
}
SA原版
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream> using namespace std; const int N = ; char s[N];
int n, sa[N], rk[N << ], oldrk[N << ], id[N], cnt[N]; int main() {
int i, m, p, w; scanf("%s", s + );
n = strlen(s + );
m = max(n, );
for (i = ; i <= n; ++i) ++cnt[rk[i] = s[i]];
for (i = ; i <= m; ++i) cnt[i] += cnt[i - ];
for (i = n; i >= ; --i) sa[cnt[rk[i]]--] = i; for (w = ; w < n; w <<= ) {
memset(cnt, , sizeof(cnt));
for (i = ; i <= n; ++i) id[i] = sa[i];
for (i = ; i <= n; ++i) ++cnt[rk[id[i] + w]];
for (i = ; i <= m; ++i) cnt[i] += cnt[i - ];
for (i = n; i >= ; --i) sa[cnt[rk[id[i] + w]]--] = id[i];
memset(cnt, , sizeof(cnt));
for (i = ; i <= n; ++i) id[i] = sa[i];
for (i = ; i <= n; ++i) ++cnt[rk[id[i]]];
for (i = ; i <= m; ++i) cnt[i] += cnt[i - ];
for (i = n; i >= ; --i) sa[cnt[rk[id[i]]]--] = id[i];
memcpy(oldrk, rk, sizeof(rk));
for (p = , i = ; i <= n; ++i) {
if (oldrk[sa[i]] == oldrk[sa[i - ]] &&
oldrk[sa[i] + w] == oldrk[sa[i - ] + w]) {
rk[sa[i]] = p;
} else {
rk[sa[i]] = ++p;
}
}
} for (i = ; i <= n; ++i) printf("%d ", sa[i]); return ;
}
去掉一个log
for (i = , k = ; i <= n; ++i) {
if (k) --k;
while (s[i + k] == s[sa[rk[i] - ] + k]) ++k;
ht[rk[i]] = k; // height太长了缩写为ht
}
height(未加st+rmq)
模板写法及变式(待更新)
询问子串[L,R]的出现次数
处理出height数组后左右二分找到第一个lcp小于R-L+1的坐标相减
求最长重复子串
max(height)即可
poj 1743
求不可重叠最长重复子串
二分答案(重复子串的长度)然后沿着sa做一遍分块,保证每个块中最多没有一个串的height小于所选答案,处理出此块中最大最小的下标,与枚举的答案长度做比较。
poj 3261
求可重叠出现k次的最长重复子串
二分答案(重复子串的长度)然后沿着sa做一遍分块,保证每个块中最多没有一个串的height小于所选答案,处理出此块中的串数是否大于k
spoj 694(重要)
求真实子串个数
len*(len-1)/2-sigma(height[i])
最长回文子串(重要)
S+'$'+反S跑一遍SA,然后分奇偶讨论情况
lcp(suf【i】,suf【n-i+1】) lcp(suf【i】,suf【n】)
poj 2406
求连续重复子串
枚举子串长度l,检验lcp(suf(0),suf(len))=n-len
poj3693
求重复次数最多的重复子串
枚举子串长度l,检验lcp(suf(0),suf(len))=n-len,求max(n/(len))
poj 2774
求最长公共子串
A+‘$’+B跑一遍sa,沿着sa求一遍不可重叠最长重复子串就ok
poj 3415
长度不小于k的公共子串个数
A+‘$’+B跑一遍sa+沿着sa搞单调栈再求不可重叠最长重复子串
未写题:
SPOJ DISUBSTR
SPOJ SUBST1
SPOJ REPEATs
POJ 3294
SPOJ PHRASEs
POJ 1226
UVA 11475
POJ 3581
POJ 3450
POJ 2758
(17/34)AC自动机/后缀数组/后缀自动机(施工中)的更多相关文章
- 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机
为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...
- loj6173 Samjia和矩阵(后缀数组/后缀自动机)
题目: https://loj.ac/problem/6173 分析: 考虑枚举宽度w,然后把宽度压位集中,将它们哈希 (这是w=2的时候) 然后可以写一下string=“ac#bc” 然后就是求这个 ...
- 【整理】如何选取后缀数组&&后缀自动机
后缀家族已知成员 后缀树 后缀数组 后缀自动机 后缀仙人掌 后缀预言 后缀Splay ? 后缀树是后缀数 ...
- POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...
- [Luogu5161]WD与数列(后缀数组/后缀自动机+线段树合并)
https://blog.csdn.net/WAautomaton/article/details/85057257 解法一:后缀数组 显然将原数组差分后答案就是所有不相交不相邻重复子串个数+n*(n ...
- SPOJ694 DISUBSTR --- 后缀数组 / 后缀自动机
SPOJ694 DISUBSTR 题目描述: Given a string, we need to find the total number of its distinct substrings. ...
- POJ2774Long Long Message (后缀数组&后缀自动机)
问题: The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to ...
- SPOJ- Distinct Substrings(后缀数组&后缀自动机)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)
求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...
随机推荐
- vue+element tree(树形控件)组件(2)
今天记录组件的代码和一个调用它的父组件的代码,接口接收数据直接传element直接能用的,也就是经过上一章函数处理过的数据以下是代码 父组件 <template> <commonfi ...
- 快速排序python实现总结
背景:数据结构与算法是IT相关的工程师一直以来的基础考察重点,很多经典书籍都是用c++或者java来实现,出于对python编码效率的喜爱,于是取search了一下python的快排实现,发现大家写的 ...
- ELK springboot日志收集
一.安装elasticsearch 可以查看前篇博客 elasticsearch安装.elasticsearch-head 安装 二.安装 配置 logstash 1.安装logstash 下载地址: ...
- 负载均衡框架 ribbon 三
Ribbon 在 SpringCloud 中的使用 1.构建 Eureka 注册中心 smart-platform-eureka1 (1)导入jar包 <properties> <p ...
- html5插件完成滚屏幕效果
首先想要完成这样的效果要用到jquery-fullpage插件我们需要他的js文件和css样式文件如图 因为是jquery的插件所以我们还要导入jquery-min.js 在页面引入这些样式和插件 ...
- 2.5D地图系统技术方案
1. 2.5D地图概述 1.1. 概述 2.5维地图就是根据dem.dom.dlg等数据,以及真三维模型在一定高度.视角和灯光效果,按照轴侧投影的方式生成的地图.本文以臻图信息ZTMapE ...
- 2653 区间xor
前言 这个题目在我之前那篇c++位运算的的随笔中提到过. 有兴趣的话去看看吧! 飞机场:https://www.cnblogs.com/laoguantongxiegogofs/p/12444517. ...
- arm 添加 samb 文件共享
编译环境: ubunto 12 arm-linux-gcc 4.3.2 arm linux 4.1.36 开发板 2440 测试上传速度,大文件 github源码 https://github.com ...
- 《ASP.NET Core 3框架揭秘》博文汇总
在过去一段时间内,写了一系列关于ASP.NET Core 3相关的文章,其中绝大部分来源于即将出版的<ASP.NET Core 3框架揭秘>(博文只能算是"初稿",与书 ...
- Simulink仿真入门到精通(五) Simulink模型的仿真
5.1 模型的配置仿真 由各种模块所构建的可视化逻辑连接,只是模型的外在表现,模型仿真的核心驱动器是被称作解算器(Solver)的组件,相当于Simulink仿真过程的心脏,驱动着模型仿真,它在每一个 ...