bzoj2754 [SCOI2012]喵星球上的点名

题目链接

AC自动机

由于输入的是恶心的数字,用了map强行带log……

由于不清楚长度,用了vector强行增加时间……

由于要判重,用了数组存下强行加常数……

慢惨了

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<string>
  7 #include<cmath>
  8 #include<ctime>
  9 #include<queue>
 10 #include<stack>
 11 #include<map>
 12 #include<set>
 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 15 #define Clear(a,b) memset(a,b,sizeof(a))
 16 #define inout(x) printf("%d",(x))
 17 #define douin(x) scanf("%lf",&x)
 18 #define strin(x) scanf("%s",(x))
 19 #define LLin(x) scanf("%lld",&x)
 20 #define op operator
 21 #define CSC main
 22 typedef unsigned long long ULL;
 23 typedef const int cint;
 24 typedef long long LL;
 25 using namespace std;
 26 void inin(int &ret)
 27 {
 28     ret=0;int f=0;char c=getchar();
 29     while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
 30     while(c>='0'&&c<='9')(ret*=10)+=c-'0',c=getchar();
 31     ret=f?-ret:ret;
 32 }
 33 int n,m,ed=1,pre[100010];
 34 vector<int>name[20020],sum[100050];
 35 map<int,int>ch[100010];
 36 map<int,int>::iterator it;
 37 void add(int id)
 38 {
 39     int x;inin(x);
 40     int temp=1;
 41     re(i,1,x)
 42     {
 43         int c;inin(c);
 44         if(!ch[temp].count(c))ch[temp][c]=++ed,temp=ed;
 45         else temp=ch[temp][c];
 46     }
 47     sum[temp].push_back(id);
 48 }
 49 queue<int>h;
 50 int V[100010],topv,M[100020],topm;
 51 int ans1[100010],ans2[100010];
 52 bool VV[100010],MM[100020];
 53 void getfail()
 54 {
 55 //    for(it=ch[0].begin();it!=ch[0].end();it++)
 56 //        h.push(it->second);
 57     h.push(1);
 58     while(!h.empty())
 59     {
 60         int x=h.front();h.pop();
 61         for(it=ch[x].begin();it!=ch[x].end();it++)
 62         {
 63             int i=it->first,v=it->second;
 64             int k=pre[x];
 65             while(!ch[k].count(i))k=pre[k];
 66             pre[v]=ch[k][i];
 67             h.push(v);
 68         }
 69     }
 70 }
 71 void GET(int id,int x)
 72 {
 73     for(int i=x;i;i=pre[i])if(!VV[i])
 74     {
 75         VV[i]=1;V[++topv]=i;
 76         re(j,0,(int)sum[i].size()-1)if(!MM[sum[i][j]])
 77         {
 78             MM[sum[i][j]]=1,M[++topm]=sum[i][j];
 79             ans1[sum[i][j]]++;
 80             ans2[id]++;
 81         }else ;
 82     }else break;
 83 }
 84 void find(int x)
 85 {
 86     int temp=1;
 87     re(i,0,(int)name[x].size()-1)
 88     {
 89         int c=name[x][i];
 90         while(!ch[temp].count(c))temp=pre[temp];
 91         temp=ch[temp][c];
 92         GET(x,temp);
 93     }
 94     re(i,1,topv)VV[V[i]]=0;
 95     re(i,1,topm)MM[M[i]]=0;
 96     topv=topm=0;
 97 }
 98 int main()
 99 {
100     re(i,-1,10000)ch[0][i]=1;
101     inin(n),inin(m);
102     re(i,1,n)
103     {
104         int x,y;
105         inin(x);
106         re(j,1,x)inin(y),name[i].push_back(y);
107         name[i].push_back(-1);
108         inin(x);
109         re(j,1,x)inin(y),name[i].push_back(y);
110     }
111     re(i,1,m)
112         add(i);
113     getfail();
114     re(i,1,n)
115         find(i);
116     re(i,1,m)printf("%d\n",ans1[i]);
117     printf("%d",ans2[1]);
118     re(i,2,n)printf(" %d",ans2[i]);
119      return 0;
120 }

 

posted @ 2016-03-01 20:39  HugeGun  阅读(221)  评论(1编辑  收藏  举报