KMP
详解链接
#include<bits/stdc++.h>
using namespace std;
const int N=1000007;
char t[N],p[N];
int next[N],flag;
void get_next(char p[],int next[]){
int len=strlen(p),i=0,j=-1;
next[0]=-1;
while(i<len){
if(j==-1||p[i]==p[j]){
i++;
j++;
if(p[i]!=p[j])next[i]=j;
else next[i]=next[j];
}else j=next[j];
}
}
void kmp(char p[],int next[]){
get_next(p,next);
int i=0,j=0;
int t_len=strlen(t),p_len=strlen(p);
while(i<t_len&&j<p_len){
if(j==-1||t[i]==p[j]){
i++;
j++;
}else j=next[j];
if(j==p_len){
printf("%d\n",i-j);
flag=1;
j=next[j];
}
}
}
int main(){
cin>>t>>p;
kmp(p,next);
}
Trie(字典树)
详解链接
#include<bits/stdc++.h>
using namespace std;
const int N=500010;
struct Trie{
int ch[N][26],id,val[N],end[N];
Trie(){
id=1;
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
memset(end,0,sizeof(end));
}
void insert(char *s,int value){
int u=0,len=strlen(s);
for(int i=0;i<len;i++){
int v=s[i]-'a';
if(!ch[u][v])ch[u][v]=id++;
u=ch[u][v];
}
end[u]=1;
}
int search(char *s){
int u=0,len=strlen(s);
for(int i=0;i<len;i++){
int v=s[i]-'a';
if(!ch[u][v])return 0;
u=ch[u][v];
}
if(end[u])return 1;else return 0;
}
}tree;
int n,m;
char s[100];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%s",s);
tree.insert(s,1);
}
cin>>m;
for(int i=1;i<=m;i++){
scanf("%s",s);
int k=tree.search(s);
if(k)printf("exit\n");
else printf("not find");
}
}
AC自动机
视频链接
详解链接
#include<bits/stdc++.h>
using namespace std;
const int N=500010;
struct AC{
int ch[N][26],val[N],fail[N],id;
void insert(char *s){
int len=strlen(s),u=0;
for(int i=0;i<len;i++){
int v=s[i]-'a';
if(!ch[u][v])ch[u][v]=++id;
u=ch[u][v];
}
val[u]++;
}
void build(){
queue<int>q;
for(int i=0;i<26;i++)
if(ch[0][i]){
fail[ch[0][i]]=0;
q.push(ch[0][i]);
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;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];
}
}
int query(char *s){
int len=strlen(s),u=0,ans=0;
for(int i=0;i<len;i++){
u=ch[u][s[i]-'a'];
for(int t=u;t&&~val[t];t=fail[t])ans+=val[t],val[t]=-1;
}
return ans;
}
}ac;
int n;
char p[1000007];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%s",p),ac.insert(p);
ac.build();
scanf("%s",p);
int ans=ac.query(p);
cout<<ans;
}
二维前缀和
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>sum[i][j];
sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
}
ans=sum[x2][y2]-sum[x1-1][y1]-sum[x1][y1-1]+sum[x1-1][y1-1];