题意:给出多个加密的模式串,和多个待匹配的串,问每个串里出现了多少种模式串。加密方法是把每3bytes加密成按6bits一个对应成4个字符,对应方法题里给了。

分析:除了解密之外,基本是个赤裸裸的AC自动机。这题要注意有多个模式串要进自动机,所以自动机的vis数组要每次清零。

#include <cstdio>
#include <queue>
#include <cstring>
#include <cctype>
using namespace std; #define D(x) const int MAX_CHILD_NUM = ;
const int MAX_NODE_NUM = * + ;
const int MAX_LEN = + ; char st[MAX_LEN];
int st2[MAX_LEN];
bool vis[MAX_NODE_NUM]; struct Trie
{
int next[MAX_NODE_NUM][MAX_CHILD_NUM];
int fail[MAX_NODE_NUM];
int count[MAX_NODE_NUM];
int node_cnt;
int root; void init()
{
node_cnt = ;
root = newnode();
} int newnode()
{
for (int i = ; i < MAX_CHILD_NUM; i++)
next[node_cnt][i] = -;
count[node_cnt++] = ;
return node_cnt - ;
} int get_id(int a)
{
return a;
} void insert(int buf[], int id)
{
int now = root;
for (int i = ; buf[i] != -; i++)
{
int id = get_id(buf[i]);
if (next[now][id] == -)
next[now][id] = newnode();
now = next[now][id];
}
count[now]++;
} void build()
{
queue<int>Q;
fail[root] = root;
for (int i = ; i < MAX_CHILD_NUM; i++)
if (next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while (!Q.empty())
{
int now = Q.front();
Q.pop();
for (int i = ; i < MAX_CHILD_NUM; i++)
if (next[now][i] == -)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
Q.push(next[now][i]);
}
}
} int query(int buf[])
{
int now = root;
int res = ;
for (int i = ; buf[i] != -; i++)
{
now = next[now][get_id(buf[i])];
int temp = now;
while (temp != root && !vis[temp])
{
res += count[temp];
// optimization: prevent from searching this fail chain again.
//also prevent matching again.
vis[temp] = true;
temp = fail[temp];
}
}
return res;
} void debug()
{
for(int i = ;i < node_cnt;i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],count[i]);
for(int j = ;j < MAX_CHILD_NUM;j++)
printf("%2d",next[i][j]);
printf("]\n");
}
}
}ac; int n, m; int get_value(char ch)
{
if (isupper(ch))
return ch - 'A';
if (islower(ch))
return ch - 'a' + ;
if (isdigit(ch))
return ch - '' + ;
if (ch == '+')
return ;
return ;
} void transform(char *st, int *st2)
{
int len = strlen(st);
int len2 = len * / ;
for (int i = ; i < len; i += )
{
int a = ;
for (int j = ; j < ; j++)
{
a = (a << ) + get_value(st[i + j]);
D(printf("**%d\n", a));
} for (int j = ; j >= ; j--)
{
st2[i * / + j] = a % ( << );
a >>= ;
D(printf("**%d\n", st2[i * / + j]));
}
}
while (st[len - ] == '=')
{
len--;
len2--;
}
st2[len2] = -;
D(puts("#"));
for (int i = ; i < len2; i++)
{
D(printf("%d ", st2[i]));
}
D(puts(""));
} void input()
{
for (int i = ; i <= n; i++)
{
scanf("%s", st);
transform(st, st2);
ac.insert(st2, i);
}
ac.build();
scanf("%d", &m);
for (int i = ; i < m; i++)
{
scanf("%s", st);
transform(st, st2);
memset(vis, , sizeof(vis));
printf("%d\n", ac.query(st2));
}
puts("");
} int main()
{ while (scanf("%d", &n) != EOF)
{
ac.init();
input();
}
return ;
}

zju3430的更多相关文章

随机推荐

  1. Log4Net使用方法

    项目里都会用到日志记录..特别是在本地跑的欢畅..一上服务器就嗝屁的时候..日志会帮你大忙.. Log4net算是一种应用的最广泛的日志记录方式了..下面来简略的说下他的用法.. 先下载log4net ...

  2. redis使用watch完成秒杀抢购功能(转)

    redis使用watch完成秒杀抢购功能: 使用redis中两个key完成秒杀抢购功能,mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表. 它的优点如下: 1. 首先选用内 ...

  3. 【10-25】OOP基础-飞机游戏知识点

    知识点 鼠标适配器类为抽象类,使用匿名子类实现鼠标事件的重写,创建一个鼠标适配器对象 添加鼠标事件监听器到JPanel对象实现鼠标的响应 创建定时器Timer对象,在定时器的任务列表方法schedul ...

  4. 在linux命令行中直接执行php命令

    有时候用浏览器调试太麻烦,想在linux命令下直接执行php代码 php -r 'echo 0500;'

  5. 网页引导:jQuery插件实现的页面功能介绍引导页效果

    现在很多网站不仅是介绍,更多的是有一些功能,怎么样让客户快速的知道网站有哪些功能呢?这里pagewalkthrough.js插件能帮我们实现,它是一个轻量级的jQuery插件,它可以帮助我们创建一个遮 ...

  6. Ubuntu 16.10 虚拟机安装记录

    一定要选自定义. 这里一定要选 稍后安装操作系统  都是坑! 启动时出现'SMBus Host Controller not enabled'错误提示,进不到图形界面. 解决办法:1.在启动Ubunt ...

  7. [设计模式] javascript 之 组合模式

    组合模式说明 组合模式用于简单化,一致化对单组件和复合组件的使用:其实它就是一棵树: 这棵树有且只有一个根,访问入口,如果它不是一棵空树,那么由一个或几个树枝节点以及子叶节点组成,每个树枝节点还包含自 ...

  8. SQL如何将A,B,C替换为'A','B','C'

    因为涉及到逗号,和单引号' 本来想一次转换成功, 但是最后貌似没有好的办法, 只有分两次完成了 select REPLACE(REPLACE('A,B,C',',','>,>'),'> ...

  9. 《JavaScript DOM 编程艺术(第2版)》读书笔记

    阅读了本书第五章关于使用JavaScript的最佳实践,大部分的建议之前都有耳闻,不过阅读之后有更深的体会. 1.防止滥用JavaScript “不管你想通过JavaScript改变哪个网页的行为,都 ...

  10. Windows Phone 开发环境的搭建

    1. 系统 系统:Windows 7(32 位).Windows 7(64 位).Windows Vista SP2(32 位)和 Windows Vista(64 位)或者更高版本. 不支持 :Wi ...