快补题别再摸鱼了(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自动机/后缀数组/后缀自动机(施工中)的更多相关文章

  1. 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机

    为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...

  2. loj6173 Samjia和矩阵(后缀数组/后缀自动机)

    题目: https://loj.ac/problem/6173 分析: 考虑枚举宽度w,然后把宽度压位集中,将它们哈希 (这是w=2的时候) 然后可以写一下string=“ac#bc” 然后就是求这个 ...

  3. 【整理】如何选取后缀数组&&后缀自动机

    后缀家族已知成员         后缀树         后缀数组         后缀自动机         后缀仙人掌         后缀预言         后缀Splay ? 后缀树是后缀数 ...

  4. POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串

    A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...

  5. [Luogu5161]WD与数列(后缀数组/后缀自动机+线段树合并)

    https://blog.csdn.net/WAautomaton/article/details/85057257 解法一:后缀数组 显然将原数组差分后答案就是所有不相交不相邻重复子串个数+n*(n ...

  6. SPOJ694 DISUBSTR --- 后缀数组 / 后缀自动机

    SPOJ694 DISUBSTR 题目描述: Given a string, we need to find the total number of its distinct substrings. ...

  7. POJ2774Long Long Message (后缀数组&后缀自动机)

    问题: The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to ...

  8. SPOJ- Distinct Substrings(后缀数组&后缀自动机)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  9. BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)

    求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...

随机推荐

  1. BTrace实战

    BTrace在解决现场问题的时候非常有用. 1.概述 1.1下载 https://github.com/btraceio/btrace,最新版本是1.3.9 目前1.3.x系列最低支持JDK1.7,要 ...

  2. IDEA激活码(可用2100年,亲测有效)

    三步骤: 1.下载rar包 2.将rar中bin包内容替换IDEA安装目录下bin内容,然后编辑idea.exe.vmoptions和idea64.exe.vmoptions文件,编辑内容一样 将最后 ...

  3. Android模拟器不能上网的解决方法

    我原来一直不用Android的模拟器,因为这东西的多年前的印象真的是很糟糕——启动半个小时,不支持OpenGL.即使后来有了x86镜像,在HAXM的支持下快的飞起,也不想用,因为NDK还要编译x86的 ...

  4. SpringCloud第二代实战系列:一文搞定Nacos实现服务注册与发现

    一.背景:SpringCloud 生态圈 在正式开始本篇文章之前我们先岔开来讲一下SpringCloud的生态圈. SpringCloud大家都比较熟悉了,它制定了分布式系统的标准规范,做了高度抽象和 ...

  5. PHP mysql事务问题实例分析

    本文实例分析了PHP的mysql事务问题.分享给大家供大家参考,具体如下: 对于myisam数据库,可以控制事务的进行: $mysqlrl = mysql_connect ( $db_config [ ...

  6. 开源项目在闲鱼、b 站上被倒卖?这是什么骚操作?

    起因 - 又是一封邮件 2020 年 3 月 2 日,收到了一封邮件,对,这次故事的起因又是一封邮件,和上次写个bug被国家信息安全漏洞共享平台抓到了一样. 这是一条评论通知邮件,一开始我以为只是正常 ...

  7. C++ for循环练习

    #include <stdio.h> //题目:现有公鸡5元一只,母鸡3元一只,小鸡1元3只(小鸡不能单买 最少3只起卖),此时顾客有100元,请问有多少种购买方案. int main() ...

  8. DVWA(七):XSS(stored)存储型XSS攻击

    存储型XSS : 存储XSS,会把攻击者的数据存储在服务器端,攻击行为将伴随着攻击数据一直存在.提交JS攻击代码存储到数据库然后再输出. low: 观察源码: <?php if( isset( ...

  9. 【TIJ4】第五章全部习题

    第五章习题 5.1 package ex0501; //[5.1]创建一个类,它包含一个未初始化的String引用.验证该引用被Java初始化成null class TestDefaultNull { ...

  10. 解决Tomcat控制台输出乱码问题

    解决Tomcat控制台输出乱码问题 打开Edit Configuration,在VM options一栏输入 -Dfile.encoding=UTF-8 然后到IDEA的bin目录找到 idea64. ...