题意:问你主串有几种模式串。但是所有串都是加密的,先解码。解码过程为:先把串按照他给的映射表变成6位数二进制数,然后首尾衔接变成二进制长串,再8位8位取变成新的数,不够的补0。因为最多可能到255,所以不能用char存,要用int。

思路:模拟乱搞一下,加个板子完事。

代码:

#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 550 * 64 + 10;
const int M = maxn * 30;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
char s[maxn];
int bit[maxn * 8], now[maxn * 8];
map<int, int> change;
void init(){
change.clear();
for(int i = 0; i <= 25; i++)
change['A' + i] = i;
for(int i = 26; i <= 51; i++)
change['a' + i - 26] = i;
for(int i = 52; i <= 61; i++)
change['0' + i - 52] = i;
change['+'] = 62;
change['/'] = 63;
}
int sp(){
int len = strlen(s);
int num = 0;
for(int i = 0; i < len; i++){
if(s[i] == '='){
num -= 2;
continue;
}
int k = change[s[i]];
for(int j = 5; j >= 0; j--){
bit[num++] = ((k & (1 << j)) == 0? 0 : 1);
}
}
int cnt = 0;
for(int i = 0; i < num; i += 8){
now[cnt] = 0;
for(int j = i; j <= i + 7; j++){
now[cnt] = now[cnt] * 2 + bit[j];
}
cnt++;
}
return cnt;
} struct Aho{
struct state{
int next[260];
int fail, cnt;
}node[maxn];
int size;
queue<int> q; void init(){
size = 0;
newtrie();
while(!q.empty()) q.pop();
} int newtrie(){
memset(node[size].next, 0, sizeof(node[size].next));
node[size].cnt = node[size].fail = 0;
return size++;
} void insert(int s[], int len, int id){
int now = 0;
for(int i = 0; i < len; i++){
int c = s[i];
if(node[now].next[c] == 0){
node[now].next[c] = newtrie();
}
now = node[now].next[c];
}
node[now].cnt = id;
} void build(){
node[0].fail = -1;
q.push(0); while(!q.empty()){
int u = q.front();
q.pop();
for(int i = 0; i < 260; i++){
if(node[u].next[i]){
if(u == 0) node[node[u].next[i]].fail = 0;
else{
int v = node[u].fail;
while(v != -1){
if(node[v].next[i]){
node[node[u].next[i]].fail = node[v].next[i];
break;
}
v = node[v].fail;
}
if(v == -1) node[node[u].next[i]].fail = 0;
}
q.push(node[u].next[i]);
}
}
}
} set<int> res;
void get(int u){ //匹配规则
while(u){
if(node[u].cnt) res.insert(node[u].cnt);
u = node[u].fail;
}
} int match(int s[], int len){
res.clear();
int ret = 0, now = 0;
for(int i = 0; i < len; i++){
int c = s[i];
if(node[now].next[c]){
now = node[now].next[c];
}
else{
int p = node[now].fail;
while(p != -1 && node[p].next[c] == 0){
p = node[p].fail;
}
if(p == -1) now = 0;
else now = node[p].next[c];
}
get(now);
}
return res.size();
}
}ac;
int main(){
init();
int n;
while(~scanf("%d", &n)){
ac.init();
for(int i = 1; i <= n; i++){
scanf("%s", s);
int len = sp();
ac.insert(now, len, i);
}
ac.build();
int m;
scanf("%d", &m);
while(m--){
scanf("%s", s);
int len = sp();
printf("%d\n", ac.match(now, len));
}
printf("\n");
}
return 0;
}

ZOJ 3430 Detect the Virus(AC自动机 + 模拟)题解的更多相关文章

  1. ZOJ - 3430 Detect the Virus —— AC自动机、解码

    题目链接:https://vjudge.net/problem/ZOJ-3430 Detect the Virus Time Limit: 2 Seconds      Memory Limit: 6 ...

  2. zoj 3430 Detect the Virus(AC自己主动机)

    题目连接:zoj 3430 Detect the Virus 题目大意:给定一个编码完的串,将每个字符相应着表的数值转换成6位二进制.然后以8为一个数值,又一次形成字符 串,推断给定询问串是否含有字符 ...

  3. ZOJ 3430 Detect the Virus

    传送门: Detect the Virus                                                                                ...

  4. ZOJ 3430 Detect the Virus(AC自动机)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430 题意:给你n个编码后的模式串,和m个编码后的主串,求原来主 ...

  5. zoj 3430 Detect the Virus(AC自己主动机)

    Detect the Virus Time Limit: 2 Seconds      Memory Limit: 65536 KB One day, Nobita found that his co ...

  6. ZOJ 3430 Detect the Virus 【AC自动机+解码】

    解码的那些事儿,不多说. 注意解码后的结果各种情况都有,用整数数组存储,char数组会超char类型的范围(这个事最蛋疼的啊)建立自动机的时候不能用0来判断结束. #include <cstdi ...

  7. ZOJ 3228 Searching the String(AC自动机)

    Searching the String Time Limit: 7 Seconds      Memory Limit: 129872 KB Little jay really hates to d ...

  8. ZOJ 4114 Detect the Virus(AC自动机)

    Detect the Virus Time Limit: 2 Seconds      Memory Limit: 65536 KB One day, Nobita found that his co ...

  9. ZOJ 3494 BCD Code(AC自动机 + 数位DP)题解

    题意:每位十进制数都能转化为4位二进制数,比如9是1001,127是 000100100111,现在问你,在L到R(R <= $10^{200}$)范围内,有多少数字的二进制表达式不包含模式串. ...

随机推荐

  1. 3A的限流芯片PW1503

    PW1503是超低RDS(ON)开关,具有可编程的电流限制,以保护电源于过电流和短路情况.它具有超温保护以及反向闭锁功能. PW1503采用薄型(1毫米)5针薄型SOT封装,提供可调版本. 特征    ...

  2. win 10下Apache和PHP的安装配置

    一.下载Apache 官网下载:https://httpd.apache.org/ 或者百度网盘链接:https://pan.baidu.com/s/17zVFNSfzzwDgFti_fboUSA 提 ...

  3. QTextEdit字符串的高亮显示问题

    20130222 鬼猫猫 整理 http://www.cnblogs.com/muyr/ 解决方法的原始地址 http://www.qtcn.org/bbs/read.php?tid=20335 背景 ...

  4. 对象存储 COS 帮您轻松搞定跨域访问需求

    背景 早期为了避免 CSRF(跨站请求伪造) 攻击,浏览器引入了 "同源策略" 机制.如果两个 URL 的协议,主机名(域名/IP),端口号一致,则视为这两个 URL " ...

  5. 通过封装openpyxl模块实现自己的Excel操作类

    """ excel类封装需要提供以下功能: 1.选择表单功能 2.读取一个单元格的数据功能 3.读取一行数据功能 4.读取表单中所有数据功能 5.往单元格中写入数据功能 ...

  6. jsaper子报表Subreport(父子报表互相传值)

    有很多人都说Jasperreports不适合中国式复杂报表,实际上运用好父子报表可以解决大部分问题了.例如下面的表.每个学生的学科数目不固定,且每个学生后有相当于小计的平均分.有点复杂度的报表,可以使 ...

  7. java架构《Socket网络编程基础篇》

    本章主要介绍Socket的基本概念,传统的同步阻塞式I/O编程,伪异步IO实现,学习NIO的同步非阻塞编程和NIO2.0(AIO)异步非阻塞编程. 目前为止,Java共支持3种网络编程模型:BIO.N ...

  8. 提高 Kafka 吞吐量

    提高 Kafka 吞吐量 1.了解分区的数据速率,以确保提供合适的数据保存空间 2.除非您有其他架构上的需要,否则在写 Topic 时请使用随机分区 3.如果 Consumers 运行的是比 Kafk ...

  9. 遇到的一个bug

    /// <summary> /// 检测玩家是否在机器人的球形碰撞体内,这个碰撞体是机器人的侦测范围,玩家在内部会进行视野检测和声音检测 /// </summary> priv ...

  10. MiniProfiler性能分析工具— .Net Core中用法

    前言: 在日常开发中,应用程序的性能是我们需要关注的一个重点问题.当然我们有很多工具来分析程序性能:如:Zipkin等:但这些过于复杂,需要单独搭建. MiniProfiler就是一款简单,但功能强大 ...