快补题别再摸鱼了(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. 基础JavaScript练习(一)总结

    任务目的 在上一任务基础上继续JavaScript的体验 接触一下JavaScript中的高级选择器 学习JavaScript中的数组对象遍历.读写.排序等操作 学习简单的字符串处理操作 任务描述 参 ...

  2. 华为物联网IoT学习笔记目录

    实验准备: 1.<小熊派功能介绍> 2.<小熊派硬件分析> 3.<STM32Cube软件安装介绍> 4.<MDK软件安装介绍> 5.<华为 IoT ...

  3. plsql乱码问题

    1,问题:在plsql 中执行sql语句,查询结果带有中文,出现乱码,即" ??? ":如下: 2,解决: 1)输入sql语句 select * from V$NLS_PARAME ...

  4. 一文深入了解史上最强的Java堆内缓存框架Caffeine

    它提供了一个近乎最佳的命中率.从性能上秒杀其他一堆进程内缓存框架,Spring5更是为了它放弃了使用多年的GuavaCache 缓存,在我们的日常开发中用的非常多,是我们应对各种性能问题支持高并发的一 ...

  5. Tomcat起不来的原因

    1.没有配java_home Tomcat是Java编写的,所以必须要java_home 2.端口被占用 怎么查看端口被占用呢?——windows 小工具:Fport.exe 3.Catalina_h ...

  6. 网络编程---socket模块

    内容中代码都是先写  server端, 再写 client端 1 TCP和UDP对比 TCP(Transmission Control Protocol)可靠的.面向连接的协议(eg:打电话).传输效 ...

  7. 五分钟学Java:如何学习Java面试必考的JVM虚拟机

    原创声明 本文首发于微信公众号[程序员黄小斜] 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 为什么要学习JVM虚拟机 最近的你有没有参加Java面试呢?你有没有发现,Java ...

  8. SpringBoot入门系列(七)Spring Boot整合Redis缓存

    前面介绍了Spring Boot 中的整合Mybatis并实现增删改查,.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/ ...

  9. 网络安全从入门到精通(第一章-2)快速自建web安全测试环境

    本文内容 动态语言 常见服务器脚本 动态语言可以做什么? 常见服务器环境快捷搭建软件 快速的搭网站的环境 CMS 1,动态语言:是对服务器行为的编程,这被称为服务器端脚本或服务器脚本. 2,常见服务器 ...

  10. Java 借助poi操作PDF工具类

    ​ 一直以来说写一个关于Java操作PDF的工具类,也没有时间去写,今天抽空写一个简单的工具类,拥有PDF中 换行,字体大小,字体设置,字体颜色,首行缩进,居中,居左,居右,增加新一页等功能,如果需要 ...