zoukankan      html  css  js  c++  java
  • BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机+map维护Trie树)

    题目大意:略

    由于字符集大,要用map维护Trie树

    并不能用AC自动机的Trie图优化,不然内存会炸

    所以我用AC自动机暴跳fail水过的

    显然根据喵星人建AC自动机是不行的,所以要根据问题建

    然而这题有一些很艮的地方:

    1.如果一个喵的名和姓都被点到,那他只被点到了一次

    2.询问的串可能相同

    3.如果map中并不包含某个元素,但你强行用数组表示它,那么它会返回0,然后这个元素会被强行插入map并赋值成0

      1 #include <map>
      2 #include <queue>
      3 #include <vector>
      4 #include <cstdio>
      5 #include <cstring>
      6 #include <algorithm>
      7 #define ll long long 
      8 #define ui unsigned int
      9 #define inf 0x3f3f3f3f
     10 #define N 100010
     11 #define imap map<int,int>::iterator
     12 using namespace std;
     13 //re
     14 int n,m;
     15 int a[N],len[N],l[N],r[N],qans[N],use[N],b[N];
     16 int gint()
     17 {
     18     int rett=0,fh=1;char c=getchar();
     19     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     20     while(c>='0'&&c<='9'){rett=(rett<<3)+(rett<<1)+c-'0';c=getchar();}
     21     return rett*fh;
     22 }
     23 struct Trie
     24 {
     25     map<int,int>ch[N];
     26     vector<int>ed[N];
     27     int val[N],fail[N],ans[N],tot;
     28     void build_trie(int j)
     29     {
     30         int x=0;
     31         for(int i=1;i<=len[j];i++){
     32             imap k=ch[x].find(a[i]);
     33             if(k==ch[x].end())
     34                 ch[x][a[i]]=++tot,val[tot]=a[i],x=tot;
     35             else x=(*k).second;
     36             if(i==len[j]) ed[x].push_back(j);
     37         }
     38     }
     39     void Build()
     40     {
     41         for(int i=1;i<=m;i++){
     42             len[i]=gint();
     43             for(int j=1;j<=len[i];j++)
     44                 a[j]=gint();
     45             build_trie(i);
     46         }
     47     }
     48     void Fail()
     49     {
     50         queue<int>q;
     51         int x=0,i,j,y,z;
     52         for(imap k=ch[0].begin();k!=ch[0].end();k++)
     53             q.push((*k).second);
     54         while(!q.empty())
     55         {
     56             x=q.front();q.pop();
     57             for(imap k=ch[x].begin();k!=ch[x].end();k++)
     58             {
     59                 i=(*k).first;
     60                 j=(*k).second;
     61                 y=fail[x];
     62                 while(!ch[y][i]&&y) 
     63                     y=fail[y];
     64                 fail[j]=ch[y][i];
     65                 q.push(j);
     66             }
     67         }
     68     }
     69     void query(int p)
     70     {
     71         int x=0;
     72         queue<int>q;
     73         for(int i=l[p];i<=r[p];i++)
     74         {
     75             while(!ch[x][b[i]]&&x)
     76                 x=fail[x];
     77             x=ch[x][b[i]];
     78             for(int j=x;j;j=fail[j])
     79                 if(ed[j].size()>0&&!use[j]){ 
     80                     for(int k=0;k<ed[j].size();k++)
     81                         ans[ed[j][k]]++,qans[p]++;
     82                     use[j]=1,q.push(j);
     83                 }
     84         }
     85         x=0;
     86         for(int i=l[p+1];i<=r[p+1];i++)
     87         {
     88             while(!ch[x][b[i]]&&x)
     89                 x=fail[x];
     90             x=ch[x][b[i]];
     91             for(int j=x;j;j=fail[j])
     92                 if(ed[j].size()>0&&!use[j]){ 
     93                     for(int k=0;k<ed[j].size();k++)
     94                         ans[ed[j][k]]++,qans[p]++;
     95                     use[j]=1,q.push(j);
     96                 }
     97         }
     98         while(!q.empty())
     99             {int x=q.front();q.pop();use[x]=0;}
    100     }
    101 }t;
    102 
    103 int main()
    104 {
    105     //freopen("name1.in","r",stdin);
    106     scanf("%d%d",&n,&m);
    107     int cnt=1;
    108     for(int i=1;i<=n*2;i++){
    109         l[i]=cnt;
    110         int num=gint();
    111         r[i]=l[i]+num-1;
    112         for(int j=l[i];j<=r[i];j++)
    113             b[j]=gint();
    114         cnt=r[i]+1;
    115     }
    116     t.Build();
    117     t.Fail();
    118     for(int i=1;i<=n*2;i+=2)
    119         t.query(i);
    120     for(int i=1;i<=m;i++)
    121         printf("%d
    ",t.ans[i]);
    122     for(int i=1;i<=n*2;i+=2)
    123         printf("%d ",qans[i]);
    124     puts("");
    125     return 0;
    126 }
  • 相关阅读:
    FindBugs详解
    Java杂项
    Ubuntu 16.04安装DB2 Express C v11.1
    h5搜索功能
    与安卓交互的上传图片 与 上传语音、视频
    获取后台轮播图图片,让其自动播放
    点赞和关注功能
    split、replace、indexof、substr 用法 (获取后台富文本框内容,截取图片)
    ttyu平台进页面获取阅读量
    图片放大预览功能
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9697151.html
Copyright © 2011-2022 走看看