码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2754 SCOI2012喵星球上的点名

时间:2018-01-22 19:29:53      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:iterator   ac自动机   mes   暴力   防止   using   space   ++i   ace   

绝世好题。

正当我犹豫不决时,hzwer说:“MAP!!!”

没错这题大大的暴力,生猛的stl,贼基尔爽,,???,,

由于我们求点名在名字中的子串个数,所以将点名建AC自动机,记录节点属于哪次点名,每次带着这位同学的所有名字去里面扫,注意判重

复杂度20000*100000以及玄学的stl复杂度。

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+10;
 4 int ans1[N],ans2[N],fail[N],n,m,cnt;
 5 map<int,int>t[N];
 6 vector<int>pos[N],a[N];
 7 queue<int>q;
 8 void build(int id)
 9 {
10     int x,k;scanf("%d",&x);int now=0;
11     for(int i=1;i<=x;++i)
12     {
13         scanf("%d",&k);
14         if(!t[now][k])t[now][k]=++cnt;
15         now=t[now][k];
16     }
17     pos[now].push_back(id);
18 }
19 void getfail()
20 {
21     for(map<int,int>::iterator i=t[0].begin();i!=t[0].end();++i)
22     {
23         int u=i->second;
24         q.push(u);
25         fail[u]=0;
26     }
27     while(!q.empty())
28     {
29         int x=q.front();q.pop();
30         for(map<int,int>::iterator i=t[x].begin();i!=t[x].end();++i)
31         {
32             int c=i->first,u=i->second;
33             q.push(u);
34             int k=fail[x];
35             while(k&&!t[k][c])k=fail[k];
36             fail[u]=t[k][c];
37         }
38     }
39 }
40 bool v[N],mark[N];
41 vector<int>H,M;
42 void get(int x,int p)
43 {
44     for(int i=p;i;i=fail[i])
45     {
46         if(v[i])return;
47         v[i]=1;H.push_back(i);
48         for(int j=0;j<pos[i].size();++j)
49         if(!mark[pos[i][j]])
50         {
51             mark[pos[i][j]]=1;
52             ans1[pos[i][j]]++;
53             ans2[x]++;
54             M.push_back(pos[i][j]);
55         }
56     }
57     return;
58 }
59 void find(int x,vector<int>g)
60 {
61     int ans=0,now=0,l=g.size();
62     for(int i=0;i<l;++i)
63     {
64         int c=g[i];
65         while(now&&!t[now][c])now=fail[now];
66         now=t[now][c];
67         get(x,now);
68     }
69     for(int i=0;i<H.size();++i)v[H[i]]=0;
70     for(int i=0;i<M.size();++i)mark[M[i]]=0;
71     H.clear();M.clear();
72     return;
73 }
74 int main()
75 {
76     scanf("%d%d",&n,&m);int x,k;
77     for(int i=1;i<=n;++i)
78     {
79         scanf("%d",&x);
80         for(int j=1;j<=x;++j)
81         scanf("%d",&k),a[i].push_back(k);
82         a[i].push_back(-1);//添加非法字符防止姓和名连在一起成一个子串
83         scanf("%d",&x);
84         for(int j=1;j<=x;++j)
85         scanf("%d",&k),a[i].push_back(k);
86     }
87     for(int i=1;i<=m;++i)build(i);
88     getfail();
89     for(int i=1;i<=n;++i)
90     find(i,a[i]);
91     for(int i=1;i<=m;++i)printf("%d\n",ans1[i]);
92     for(int i=1;i<n;++i)printf("%d ",ans2[i]);
93     printf("%d",ans2[n]);
94     return 0;
95 }

 

BZOJ2754 SCOI2012喵星球上的点名

标签:iterator   ac自动机   mes   暴力   防止   using   space   ++i   ace   

原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8330171.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!