e-Government

e-Government

/*
如果没有修改操作,那就是首先建立ac自动机
然后跑出现了多少次的问题

但是增加了一个修改的操作

如果没有了还删除,那么将不影响
或者有了还进行添加,也不影响

也就是要处理多次查询的问题

区间查询,单点修改

*/
#include <bits/stdc++.h>
using namespace std;
const int M=1e6+5;
using ll =long long;

bool vis[M];

int ch[M][26],flag[M],id[M],fail[M],tot;
void insert(string s,int ID) {
    int p=0;
    for(int i=0;i<s.length();i++) {
        int v=s[i]-'a';
        if(ch[p][v]==0)ch[p][v]=++tot;
        p=ch[p][v];
    }
    flag[p]=1;
    id[ID]=p;
}

void build() {
    queue<int>q;
    for(int i=0;i<26;i++)
        if(ch[0][i])q.push(ch[0][i]);
    while(!q.empty()) {
        int now=q.front();q.pop();
        for(int i=0;i<26;i++) {
            if(ch[now][i]) {
                fail[ch[now][i]]=ch[fail[now]][i];
                q.push(ch[now][i]);
            }
            else ch[now][i]=ch[fail[now]][i];
        }
    }
}

int L[M],R[M],cnt;
vector<int>g[M];
void dfs(int now,int fa) {
    L[now]=++cnt;
    for(auto to:g[now])
        if(to!=fa)dfs(to,now);
    R[now]=cnt;
}

ll c[M];
int lowbit(int x) {
    return x&-x;
}

void add(int i,int v) {
    while(i<=cnt) {
        c[i]+=v;
        i+=lowbit(i);
    }
}

ll query(int i) {
    ll ans=0;
    while(i) {
        ans+=c[i];
        i-=lowbit(i);
    }
    return ans;
}

ll query(string s) {
    ll p=0,ans=0;
    //匹配的位置是对的
    for(int i=0;i<s.length();i++) {
        int v=s[i]-'a';
        p=ch[p][v];
        ans+=query(L[p]);
    }
    return ans;
}

void up(int i,int v) {
    add(L[i],v);add(R[i]+1,-v);
}

int main() {
    int n,k;cin>>n>>k;
    for(int i=1;i<=k;i++) {
        string s;cin>>s;
        insert(s,i);
        vis[i]=1;
    }
    build();
    for(int i=1;i<=tot;i++)g[fail[i]].push_back(i);
    dfs(0,0);//建树完成,然后直接进行修改就可以了
    //首先把所有的点都给标记上就可以了
    for(int i=1;i<=tot;i++)if(flag[i])up(i,1);
    for(int i=1;i<=n;i++) {
        char op;cin>>op;
        if(op=='?') {
            string s;cin>>s;
            cout<<query(s)<<endl;
        }
        else {
            int x;cin>>x;
            if(op=='+'&&vis[x]==0)vis[x]=1,up(id[x],1);
            else if(op=='-'&&vis[x])vis[x]=0,up(id[x],-1);
        }
    }
    return 0;
}
posted @ 2023-04-17 17:15  basicecho  阅读(32)  评论(0)    收藏  举报