求条啊
查看原帖
求条啊
322792
Alea楼主2023/10/12 11:28

这是赤果果的二进制分组 AC 自动机不幸的是它 MLE 了。

#include <iostream>
#include <queue>
#include <string>
#include <cmath>
using namespace std;
struct ACAM{
    const static int SIGMA=26;
    vector<vector<int>> trans,bktr;
    vector<int> fail,ed;
    bool changed,got;
    int tot,root,tans=0;
    ACAM(int ze){
        fail=vector<int>((ze+1)*SIGMA,0),ed=vector<int>((ze+1)*SIGMA);
        //fail.resize(ze+1),ed.resize(ze+1);
        bktr=trans=vector<vector<int>>((ze+1)*SIGMA,vector<int>(SIGMA,0));
        // trans.resize(ze+1,vector<int>(SIGMA));
        root=tot=1,changed=got=false;
    }
    void insert(string st){
        if(!changed) trans=bktr;
        int co=root;
        for(auto ch:st){
            if(trans[co][ch-'a']==0) trans[co][ch-'a']=(++tot);
            co=trans[co][ch-'a'];
        }
        ed[co]++,changed=true,got=false;
    }
    void build(){
        if(!changed) return;
        changed=false,got=false;
        bktr=trans,fail=vector<int>(fail.size(),0);
        queue<int> que;
        for(int i=0;i<SIGMA;i++) trans[0][i]=1;
        que.push(1),fail[1]=0;
        while(!que.empty()){
            int co=que.front();que.pop();
            for(int i=0;i<SIGMA;i++){
                if(trans[co][i]) fail[trans[co][i]]=trans[fail[co]][i],que.push(trans[co][i]);
                else trans[co][i]=trans[fail[co]][i];
            }
        }
    }
    int query(string st){
        if(got) return tans;
        got=true;
        int co=root,ans=0;
        for(auto ch:st){
            co=trans[co][ch-'a'];
            for(int nw=co;nw!=0;nw=fail[nw]) ans+=ed[nw];
        }
        return tans=ans;
    }
}inserted[15]={ACAM(2),ACAM(4),ACAM(8),ACAM(16),ACAM(32),ACAM(64),ACAM(128),ACAM(256),ACAM(512),ACAM(1024),ACAM(2048),ACAM(4096),ACAM(8192),ACAM(16384),ACAM(32768)},
deleted[15]={ACAM(2),ACAM(4),ACAM(8),ACAM(16),ACAM(32),ACAM(64),ACAM(128),ACAM(256),ACAM(512),ACAM(1024),ACAM(2048),ACAM(4096),ACAM(8192),ACAM(16384),ACAM(32768)};
int main(){
    int m,t;
    string st;
    cin>>m;
    while(m--){
        cin>>t>>st;
        if(t==1||t==2){
            int lon=log2(st.length());
            if(t==1) inserted[lon].insert(st);
            else deleted[lon].insert(st);
        }else{
            int ins=0,del=0;
            for(int i=0;i<15;i++){
                inserted[i].build();
                deleted[i].build();
                ins+=inserted[i].query(st);
                del+=deleted[i].query(st);
            }
            cout<<ins-del<<endl;
        }
    }
    return 0;
}
2023/10/12 11:28
加载中...