2754: [SCOI2012]喵星球上的点名

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 649  Solved: 305
[Submit][Status]

Description

a180285幸运地被选做了地球到喵星球的留学生。他发现喵星人在上课前的点名现象非常有趣。   假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成。喵星球上的老师会选择M个串来点名,每次读出一个串的时候,如果这个串是一个喵星人的姓或名的子串,那么这个喵星人就必须答到。 然而,由于喵星人的字码过于古怪,以至于不能用ASCII码来表示。为了方便描述,a180285决定用数串来表示喵星人的名字。
现在你能帮助a180285统计每次点名的时候有多少喵星人答到,以及M次点名结束后每个喵星人答到多少次吗?  

Input

 
现在定义喵星球上的字符串给定方法:
先给出一个正整数L,表示字符串的长度,接下来L个整数表示字符串的每个字符。
输入的第一行是两个整数N和M。
接下来有N行,每行包含第i 个喵星人的姓和名两个串。姓和名都是标准的喵星球上的
字符串。
接下来有M行,每行包含一个喵星球上的字符串,表示老师点名的串。

Output

 
对于每个老师点名的串输出有多少个喵星人应该答到。
然后在最后一行输出每个喵星人被点到多少次。

Sample Input

2 3
6 8 25 0 24 14 8 6 18 0 10 20 24 0
7 14 17 8 7 0 17 0 5 8 25 0 24 0
4 8 25 0 24
4 7 0 17 0
4 17 0 8 25

Sample Output

2
1
0
1 2
【提示】
事实上样例给出的数据如果翻译成地球上的语言可以这样来看
2 3
izayoi sakuya
orihara izaya
izay
hara
raiz

HINT

【数据范围】

对于30%的数据,保证:

1<=N,M<=1000,喵星人的名字总长不超过4000,点名串的总长不超过2000。

对于100%的数据,保证:

1<=N<=20000,1<=M<=50000,喵星人的名字总长和点名串的总长分别不超过100000,保证喵星人的字符串中作为字符存在的数不超过10000。

Source

很裸很裸的AC自动机。只不过这道题让我基本搞懂了stl map的用法。

map.insert(pair) 插入映射关系

map.find(x) 查询x映射的关系,返回一个迭代器,可用first,second查找

map<int,int>::iterator it1; 迭代器

另外AC自动机的一个小细节,让我Wa了两遍:

fail指针如果需要指向深度为1的节点时要特判,而且对于已经确定fail指针的节点,切忌重新复制(其实就是if语句条件要严密)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
#define MAXT 201000
#define MAXN MAXT
vector<int> query[MAXN];
int query_gets[MAXN];
int cat_gets[MAXN];
int qur_vis[MAXN];
int topq=-;
struct aaa
{
int id;
int fail;
int qur_id;
map<int,int> next;
aaa()
{
qur_id=id=fail=-;
}
};
int root;
aaa tree[MAXT];
int topt=;
int name[MAXN],topn=-;
int str[MAXN];
int n,m; void add_str(int * str,int qur)
{
int ind;
int now=root;
map<int,int>::iterator it1;
while (*str!=-)
{
ind=*(str++);
it1=tree[now].next.find(ind);
if (it1==tree[now].next.end())
{
tree[now].next.insert(make_pair(ind,++topt));
tree[topt].id=ind;
now=topt;
}else
{
now=it1->second;
}
}
if (tree[now].qur_id==-)
{
tree[now].qur_id=++topq;
query[topq].push_back(qur);
}else
{
query[tree[now].qur_id].push_back(qur);
}
}
int q[MAXT];
void build_tree()
{
int ope=,clo=,now,temp,x,ind;
map<int,int>::iterator it1,it2;
tree[].fail=;
for (it1=tree[].next.begin();it1!=tree[].next.end();it1++)
{
now=it1->second;
q[++clo]=now;
tree[now].fail=;
}
while (ope<clo)
{
now=q[++ope];
for (it1=tree[now].next.begin();it1!=tree[now].next.end();it1++)
{
x=it1->second;
ind=it1->first;
q[++clo]=x;
temp=tree[now].fail;
while (temp!=root)
{
it2=tree[temp].next.find(ind);
if (it2!=tree[temp].next.end())
{
tree[x].fail=it2->second;
break;
}
temp=tree[temp].fail;
}
it2=tree[root].next.find(ind);
if (tree[x].fail==-&&it2!=tree[root].next.end())//Oh, I forgot this part again
{
tree[x].fail=it2->second;
}
if (tree[x].fail==-)
{
tree[x].fail=;
}
}
}
} int count_str(int *str,int cat_id)
{
int ret=;
int now=;
int ind,x,temp;
int i;
map<int,int>::iterator it1;
while (*str!=-)
{
ind=*(str++);
it1=tree[now].next.find(ind);
while (now!=root&&it1==tree[now].next.end())
{
now=tree[now].fail;
it1=tree[now].next.find(ind);
}
if (it1==tree[now].next.end())
{
now=root;
}else
{
now=it1->second;
}
temp=now;
while (temp!=root)
{
if (tree[temp].qur_id!=-)
{
x=tree[temp].qur_id;
for (i=;i<query[x].size();i++)
{
if(qur_vis[query[x][i]]!=cat_id)
{
query_gets[query[x][i]]++;
ret++;
qur_vis[query[x][i]]=cat_id;
}
}
}
temp=tree[temp].fail;
} }
return ret;
}
void init()
{
topt=;
tree[].id=-;
root=;
int i,j,x,y;
scanf("%d%d",&n,&m);
for (i=;i<n*;i++)
{
scanf("%d",&x);
name[++topn]=x;
for (j=;j<x;j++)
{
scanf("%d",&y);
name[++topn]=y;
}
name[++topn]=-;
}
for (i=;i<m;i++)
{
scanf("%d",&x);
for (j=;j<x;j++)
{
scanf("%d",&y);
str[j]=y;
}
str[x]=-;
add_str(str,i);
}
build_tree();
memset(qur_vis,-,sizeof(qur_vis));
}
void work()
{
int i;
int now=;
for (i=;i<n*;i++)
{
now++;
cat_gets[i/]+=count_str(&name[now],i/);
now+=name[now-];
now++;
}
for (i=;i<m;i++)
{
printf("%d\n",query_gets[i]);
}
for (i=;i<n-;i++)
{
printf("%d ",cat_gets[i]);
}
printf("%d\n",cat_gets[n-]);
}
int main()
{
init();
work();
return ;
}

BZOJ 2754: [SCOI2012]喵星球上的点名的更多相关文章

  1. BZOJ 2754: [SCOI2012]喵星球上的点名 [后缀数组+暴力]

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1906  Solved: 839[Submit][St ...

  2. BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1902  Solved: 837[Submit][St ...

  3. 【刷题】BZOJ 2754 [SCOI2012]喵星球上的点名

    Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串来点 ...

  4. bzoj 2754 [SCOI2012]喵星球上的点名(后缀数组)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2754 [题意] 每只喵有名姓,如果被老师点到名或姓的子串都要答道,但每只喵一次点名只答 ...

  5. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)

    吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...

  6. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机+map维护Trie树)

    题目大意:略 由于字符集大,要用map维护Trie树 并不能用AC自动机的Trie图优化,不然内存会炸 所以我用AC自动机暴跳fail水过的 显然根据喵星人建AC自动机是不行的,所以要根据问题建 然而 ...

  7. bzoj 2754: [SCOI2012]喵星球上的点名【AC自动机】

    洛谷90,最后一个点死活卡不过去(也可能是我写的有问题? 比较暴力的做法,把询问带着标号建立AC自动机,用map存儿子. 然后用名字串在自动机上跑,以为是名或姓的子串就行所以把名和姓中间加个特殊字符拼 ...

  8. 2754. [SCOI2012]喵星球上的点名【后缀数组】

    Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣.   假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串 ...

  9. BZOJ2754: [SCOI2012]喵星球上的点名

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 680  Solved: 314[Submit][Sta ...

随机推荐

  1. android 60 发送短信

    import android.os.Bundle; import android.app.Activity; import android.telephony.SmsManager; import a ...

  2. 如何正确合理的建立MYSQL数据库索引

    索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型. 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytabl ...

  3. linux bash下 快捷键

    c + a # 光标跳转到最左 c + e # 光标跳转到最后 c + w # 删除最后输入的单词 c + u # 删除整行 c + k # 删除光标到末尾 c + l # 清屏 c + z # 挂起 ...

  4. Tomcat集群,Nginx集群,Tomcat+Nginx 负载均衡配置,Tomcat+Nginx集群

    Tomcat集群,Nginx集群,Tomcat+Nginx 负载均衡配置,Tomcat+Nginx集群 >>>>>>>>>>>> ...

  5. api图片传输,转成64位字符串进行传输

    byte[] getImageByte = HttpHelper.getImageByte(HttpContext.Current.Server.MapPath(("~/UploadFile ...

  6. Frequent Pattern 挖掘之二(FP Growth算法)(转)

    FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达到这样的效果,它采用了一种简洁的数据结 ...

  7. HTML 转义字符

    在HTML中,一个包含特殊字符(如<>&)的字符串,要显示在页面上,由于添加到文本节点时会被认为是HTML的标签结构,造成一些错误,因此,要将这些特殊字符进行转义. 例如在< ...

  8. android中sharedPreferences的笔记

    haredPreferences的使用非常简单,能够轻松的存放数据和读取数据.SharedPreferences只能保存简单类型的数据,例如,String.int等.一般会将复杂类型的数据转换成Bas ...

  9. hibernate - 何时关闭数据库

    ref: http://www.coderanch.com/t/637103/ORM/databases/close-database-connection-hibernate 我上这个问题, 原因是 ...

  10. ios专题 - 安全

    iOS通过以下几种机制来保全整个系统的安全性: 一:系统结构 所有iOS设备中,系统与硬件都高度集成,从系统启动.系统更新.应用的安装.应用的运行时等多个方面来保全系统的安全,具体包括: 1:所有iO ...