题意:给出多个加密的模式串,和多个待匹配的串,问每个串里出现了多少种模式串。加密方法是把每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. Javascript验证手机号码正则表达式

    //验证手机正则 var flag = !!phone.match(/^(0|86|17951)?(13[0-9]|15[012356789]|17[0-9]|18[0-9]|14[0-9])[0-9 ...

  2. CentOS7 mono环境连接WCF

    总结下在mono环境中使用Wcf出现的问题以帮助你快速解决问题. 1.昨天在内网Centos7下部署由Windows上开发完成的ASP.NET Mvc4项目,部署到mono环境下遇到了无法找到endp ...

  3. mysql计划任务每天定时执行

    代码例子:CREATE EVENT `course_listener` ON SCHEDULE EVERY DAY STARTS '2012-07-18 00:00:00' ON COMPLETION ...

  4. Java Programming Test Question 3

    import java.util.HashSet; public class JPTQuestion3 { public static void main(String[] args) { HashS ...

  5. C#对HTML文档的解析

    http://www.2cto.com/kf/201312/268777.html http://jingyan.baidu.com/article/7e44095334bb162fc0e2efad. ...

  6. 2015年12月01日 GitHub入门学习(一)GitHub简介

    序:Github理念是Social Coding(社会化编程).octocat是它的吉祥物. 一.Github与Git的区别与联系 区别:GIT是仓库,Github是提供一种将代码提交到Git仓库的服 ...

  7. mac安装mongodb

    一,安装方法1 ,下载mongodb 1,官网下载mongodb程序 https://www.mongodb.org/downloads#production​ 2,解压后启动mongodb服务 下载 ...

  8. js中的json

    1.什么是JSON? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 2.JSON语法是JavaScr ...

  9. nginx反向代理、根据浏览器分离访问

    环境根据http://www.cnblogs.com/zzzhfo/p/6032095.html配置 修改LB的/usr/local/nginx/conf/nginx.conf upstream st ...

  10. 9 patch png 的上下左右

    9 patch png 的上下左右   前言: 9 patch png 图片,扩展名为.9.png,是一个标准的PNG图像,它包括额外的1个像素的边界,通过对这个边界的描述来达到我们预期的拉伸效果.a ...