SCOI2012」喵星球上的点名 AC自动机 暴力法 求卡
  • 板块学术版
  • 楼主xcyyyyyy
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/6/15 17:21
  • 上次更新2023/10/23 13:06:17
查看原帖
SCOI2012」喵星球上的点名 AC自动机 暴力法 求卡
691447
xcyyyyyy楼主2023/6/15 17:21

单纯好奇

#include<bits/stdc++.h>
using namespace std;
int n,m;
vector<int> cat[50005];int ans[50005];
int all[400005],sum[400005];
int tire[400005][12],fail[400005],vis[400005],st[400005],top,tot;
int mp[100005];
void insert(vector<int> &num,int ID){
    int p=0;
    for(int i=0;i<num.size();i++){
        if(!tire[p][num[i]])tire[p][num[i]]=++tot;
        p=tire[p][num[i]];
    }
    ++sum[p];
    mp[ID]=p;
}
void build(){
    queue<int> Q;
    for(int i=0;i<12;i++)if(tire[0][i])
        Q.push(tire[0][i]);
    while(Q.size()){
        int u=Q.front();
        Q.pop();
        for(int i=0;i<12;i++)
            if(tire[u][i]){
                fail[tire[u][i]]=tire[fail[u]][i];
                Q.push(tire[u][i]);
            }
            else
                tire[u][i]=tire[fail[u]][i];
    }
}
int query(vector<int> num){
    while(top)vis[st[top--]]=0;
    int p=0,ans=0;
    for(int i=0;i<num.size();i++){
        p=tire[p][num[i]];
        for(int j=p;!vis[j]&&j;j=fail[j]){
            ans+=sum[j];
            vis[j]=1;st[++top]=j;++all[j];
        }
    }
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,len,x;i<=n;i++){
        scanf("%d",&len);
        cat[i].push_back(10);
        while(len--){
            scanf("%d",&x);
            do{cat[i].push_back(x%10),x/=10;}while(x);
            cat[i].push_back(10);
        }
        cat[i].push_back(11);
        cat[i].push_back(10);
        scanf("%d",&len);
        while(len--){
            scanf("%d",&x);
            do{cat[i].push_back(x%10),x/=10;}while(x);
            cat[i].push_back(10);
        }
    }
    for(int i=1,len,x;i<=m;i++){
        vector<int> num;
        num.push_back(10);
        scanf("%d",&len);
        while(len--){
            scanf("%d",&x);
            do{num.push_back(x%10),x/=10;}while(x);
            num.push_back(10);
        }
        insert(num,i);
    }
    build();
    for(int i=1;i<=n;i++)ans[i]=query(cat[i]);
    for(int i=1;i<=m;i++)printf("%d\n",all[mp[i]]);
    for(int i=1;i<=n;i++)printf("%d ",ans[i]);
}
2023/6/15 17:21
加载中...