BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]
2754: [SCOI2012]喵星球上的点名
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 1902 Solved: 837
[Submit][Status][Discuss]
Description
Input
Output
HINT
【数据范围】
对于30%的数据,保证:
1<=N,M<=1000,喵星人的名字总长不超过4000,点名串的总长不超过2000。
对于100%的数据,保证:
1<=N<=20000,1<=M<=50000,喵星人的名字总长和点名串的总长分别不超过100000,保证喵星人的字符串中作为字符存在的数不超过10000。
喵~ http://www.cnblogs.com/candy99/p/cat.html
首先想到两问建两个AC自动机,第一问是把喵名建自动机然后点名串统计fail子树,但是不对啊啊啊啊啊人家一个喵就算一次.....
所以就发现其他人用了个很暴力的方法,点名串建AC自动机然后喵在上面跑,每跑一个字符暴力统计更新fail指向的点名串......然后就过了
一些细节:
1.要用map 字符集太大(离散化并没有用) 这样建AC自动机的时候就不能用Trie图优化了用普通做法
2.一个喵统计点名串需要用个vis[],从黄学长哪里学到了黑科技用个vector记录vis了那些,不用memset直接把vector里的还原行了
3.可能有重复点名串!!!!!
4.姓和名用个特殊数字连起来行了
980ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
const int N=1e5+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
} int n,m,k;
vector<int> a[N];
struct node{
map<int,int> ch;
int fail,val;
vector<int> s;
}t[N];
int sz;
void ins(int id){
int u=,n=read();
for(int i=;i<=n;i++){
int c=read();
if(!t[u].ch[c]) t[u].ch[c]=++sz;
u=t[u].ch[c];
}
t[u].s.push_back(id);
}
int q[N],head,tail;
map<int,int>::iterator it,it2;
void getAC(){
head=tail=;
for(it=t[].ch.begin();it!=t[].ch.end();it++)
q[tail++]=it->second;
while(head!=tail){
int u=q[head++];
for(it=t[u].ch.begin();it!=t[u].ch.end();it++){
int v=it->second,c=it->first;
int now=t[u].fail;
while(now&&!t[now].ch.count(c)) now=t[now].fail;
if(t[now].ch.count(c)) t[v].fail=t[now].ch[c];
else t[v].fail=now;//
q[tail++]=v;
}
}
} int a1[N],a2[N];
bool vis[N];
vector<int> V;
void update(int u,int id){
for(;u;u=t[u].fail){
if(vis[u]) break;
vis[u]=;
V.push_back(u);
for(int i=;i<t[u].s.size();i++)
a1[t[u].s[i]]++,a2[id]++;
}
}
void runAC(int id){
vector<int> &s=a[id];
int u=,n=s.size();
for(int i=;i<n;i++){
while(u&&!t[u].ch.count(s[i])) u=t[u].fail;
if(t[u].ch.count(s[i])) u=t[u].ch[s[i]];
update(u,id);
}
for(int i=;i<V.size();i++) vis[V[i]]=;
V.clear();
}
void solve(){
getAC();
for(int i=;i<=n;i++) runAC(i);
for(int i=;i<=m;i++) printf("%d\n",a1[i]);
for(int i=;i<=n;i++) {printf("%d",a2[i]);if(i!=n) putchar(' ');}
}
int main(){
freopen("in","r",stdin);
n=read();m=read();
for(int i=;i<=n;i++){
k=read();while(k--) a[i].push_back(read());
a[i].push_back(-);
k=read();while(k--) a[i].push_back(read());
}
for(int i=;i<=m;i++) ins(i);
solve();
}
BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]的更多相关文章
- BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机+map维护Trie树)
题目大意:略 由于字符集大,要用map维护Trie树 并不能用AC自动机的Trie图优化,不然内存会炸 所以我用AC自动机暴跳fail水过的 显然根据喵星人建AC自动机是不行的,所以要根据问题建 然而 ...
- BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)
吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...
- BZOJ 2754: [SCOI2012]喵星球上的点名
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 649 Solved: 305[Submit][Sta ...
- BZOJ 2754: [SCOI2012]喵星球上的点名 [后缀数组+暴力]
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1906 Solved: 839[Submit][St ...
- 【刷题】BZOJ 2754 [SCOI2012]喵星球上的点名
Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串来点 ...
- BZOJ2754: [SCOI2012]喵星球上的点名(AC自动机)
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2816 Solved: 1246[Submit][Status][Discuss] Descript ...
- BZOJ2754: [SCOI2012]喵星球上的点名(AC自动机/后缀自动机)
Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串 ...
- bzoj 2754 [SCOI2012]喵星球上的点名(后缀数组)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2754 [题意] 每只喵有名姓,如果被老师点到名或姓的子串都要答道,但每只喵一次点名只答 ...
- bzoj 2754: [SCOI2012]喵星球上的点名【AC自动机】
洛谷90,最后一个点死活卡不过去(也可能是我写的有问题? 比较暴力的做法,把询问带着标号建立AC自动机,用map存儿子. 然后用名字串在自动机上跑,以为是名或姓的子串就行所以把名和姓中间加个特殊字符拼 ...
随机推荐
- javascript如何处理多级的实时监听
今日工作中遇到需求,要求js代码对表单中的input内容进行实时监听,当input中的值改变时触发一些事件. 按照常规思维,代码很快写完了. $(function () { $("#inpu ...
- 基于ARM的车牌识别技术研究与实现
在云盘里包含了我本科毕业设计的全部资料和代码.主要涉及下面摘要中的几个部分.虽然系统无法实用,但是适合机器视觉和嵌入式方向的入门.希望能对有志从事相关方向的朋友有所帮助.本人现在在深圳从事机器视觉算法 ...
- github 中删除仓库
删除时,填充的名字是库的名字
- Java面试经
最近趁有空整理下面试经常会被问到的知识点,参考的资料都是本人通过百度而挑选出来的,具有一定的参考意义. 一 .java基础1.String和StringBuffer.StringBuild的区别:ht ...
- java中的nextLine
package scanner; import java.util.Scanner; public class NextLine { public static void main(String[] ...
- 配置shiro错误
在web配置工程中配置shiro,如果启动Tomcat,报错:org.apache.shiro.web.config.WebIniSecurityManagerFactory.setDefaults ...
- [知了堂学习笔记]_Java代码实现MySQL数据库的备份与还原
通常在MySQL数据库的备份和恢复的时候,多是采用在cmd中执行mysql命令来实现. 例如: mysqldump -h127.0.0.1 -uroot -ppass test > d:/tes ...
- python3 第二十一章 - 函数式编程之return函数和闭包
我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_sum(*args): ax = 0 for n in args: ax = ax + n return ax 但 ...
- JS题目
1.请你谈谈Cookie的弊端 cookie虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但还是有很多局限性的. 第一:每个特定的域名下最多生成20个cookie 1.IE6或更低版本最 ...
- wstring操作与普通段字符操作对照表
字符分类: 宽字符函数普通C函数描述 iswalnum() isalnum() 测试字符是否为数字或字母 iswalpha() isalpha() 测试字符是否是字母 ...