Barty's Computer 字典树
https://nanti.jisuanke.com/t/17122
Barty have a computer, it can do these two things.
Add a new string to its memory, the length of this string is even.
For given 44 strings a,b,c,da,b,c,d, find out how many strings that can be product by a+s1+b+c+s2+da+s1+b+c+s2+d, and |a| + |s1| + |b| = |c| + |s2| + |d|∣a∣+∣s1∣+∣b∣=∣c∣+∣s2∣+∣d∣. |s|∣s∣ means the length of string ss, s1s1 and s2s2 can be any string, including
"".
Please help your computer to do these things.
Input Format
Test cases begins with T(T \le 5)T(T≤5).
Then TT test cases follows.
Each test case begins with an integer Q(Q \le 30000)Q(Q≤30000).
Then QQ lines,
1 s: add a new string ss to its memory.
2 a b c d: find how many strings satisfying the requirement above.
\sum |s| + |a| + |b| + |c| + |d| \le 2000000∑∣s∣+∣a∣+∣b∣+∣c∣+∣d∣≤2000000.
Output Format
For type 22 query. Output the answer in one line.
样例输入
1
10
1 abcqaq
1 abcabcqaqqaq
2 ab bc qa aq
2 a c q q
1 abcabcqaqqwq
2 ab bc qa aq
2 a c q q
1 abcq
2 a c q q
2 a b c q
样例输出
1
2
1
3
3
1
题目来源
首先对于每一个主串,都把它对半砍,前缀加入字典树0,前缀逆序加入字典树1,后缀加入字典树2,后缀逆序加入字典树3
所以每一个节点都开一个vector存着有哪些主串能经过这个节点。内存复杂度玄学
然后每次询问,用a去字典树0找,就能知道有哪些主串能匹配a
同理b、c、d,然后求一个交集即可。
这样会有些不合法
比如就是会使得
ab bc这样,结合成abc
所以要用长度来判断是否合法,
lenstr(a) + lenstr(b)不能大于lenstr (s) / 2
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int N = , maxn = 2e6 + ;
struct Node {
vector<int> vc;
struct Node * pNext[N];
} tree[][ + ];
int t[];
int len[maxn];
char str[maxn];
char a[maxn], b[maxn], c[maxn], d[maxn];
struct Node * create(int id) {
struct Node * p = &tree[id][t[id]++];
p->vc.clear();
for (int i = ; i < N; ++i) p->pNext[i] = NULL;
return p;
}
void toInset(struct Node **T, char str[], int be, int en, int flag, int id, int which) {
struct Node *p = *T;
if (p == NULL) {
p = *T = create(id);
}
if (flag == -) {
for (int i = en; i >= be; --i) {
int tid = str[i] - 'a';
if (!p->pNext[tid]) p->pNext[tid] = create(id);
p = p->pNext[tid];
p->vc.push_back(which);
}
} else {
for (int i = be; i <= en; ++i) {
int tid = str[i] - 'a';
if (!p->pNext[tid]) {
p->pNext[tid] = create(id);
}
p = p->pNext[tid];
p->vc.push_back(which);
}
}
}
int vis[][maxn], DFN;
bool flag;
void ask(struct Node *T, char str[], int be, int en, int flag, int which) {
struct Node *p = T;
if (p == NULL) {
flag = true;
return;
}
if (flag == -) {
for (int i = en; i >= be; --i) {
int id = str[i] - 'a';
if (!p->pNext[id]) {
flag = true;
return ;
}
p = p->pNext[id];
}
for (int i = ; i < p->vc.size(); ++i) {
vis[which][p->vc[i]] = DFN;
}
} else {
for (int i = be; i <= en; ++i) {
int id = str[i] - 'a';
if (!p->pNext[id]) {
flag = true;
return ;
}
p = p->pNext[id];
}
// printf("fff");
// printf("%d * * ** \n", p->vc.size());
for (int i = ; i < p->vc.size(); ++i) {
vis[which][p->vc[i]] = DFN;
}
}
}
void work() {
t[] = t[] = t[] = t[] = ;
struct Node *T[];
for (int i = ; i < ; ++i) T[i] = NULL;
int q;
scanf("%d", &q);
int now = ;
while (q--) {
int op;
scanf("%d", &op);
if (op == ) {
scanf("%s", str + );
len[++now] = strlen(str + );
toInset(&T[], str, , len[now] / , , , now);
toInset(&T[], str, , len[now] / , -, , now);
toInset(&T[], str, len[now] / + , len[now], , , now);
toInset(&T[], str, len[now] / + , len[now], -, , now);
} else {
scanf("%s%s%s%s", a + , b + , c + , d + );
++DFN, flag = false;
int lena = strlen(a + ), lenb = strlen(b + ), lenc = strlen(c + ), lend = strlen(d + );
ask(T[], a, , lena, , );
if (flag) {
printf("0\n");
continue;
}
ask(T[], b, , lenb, -, );
if (flag) {
printf("0\n");
continue;
}
ask(T[], c, , lenc, , );
if (flag) {
printf("0\n");
continue;
}
ask(T[], d, , lend, -, );
if (flag) {
printf("0\n");
continue;
}
int ans = ;
// for (int i = 1; i <= now; ++i) {
// printf("%d %d %d %d\n", vis[0][i], vis[1][i], vis[2][i], vis[3][i]);
// }
// printf("*************\n");
for (int i = ; i <= now; ++i) {
if (vis[][i] == DFN && vis[][i] == DFN && vis[][i] == DFN && vis[][i] == DFN && lena + lenb <= len[i] / && lenc + lend <= len[i] / )
ans++;
}
printf("%d\n", ans);
}
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return ;
}
Barty's Computer 字典树的更多相关文章
- ACM: Gym 100935F A Poet Computer - 字典树
Gym 100935F A Poet Computer Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d &am ...
- 字典树 - A Poet Computer
The ACM team is working on an AI project called (Eih Eye Three) that allows computers to write poems ...
- 字典树(Trie树)实现与应用
一.概述 1.基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种. 2.基本性质 根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点.路径上 ...
- Trie(前缀树/字典树)及其应用
Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree.当然很多名字的意义其实有交 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- 字典树+博弈 CF 455B A Lot of Games(接龙游戏)
题目链接 题意: A和B轮流在建造一个字,每次添加一个字符,要求是给定的n个串的某一个的前缀,不能添加字符的人输掉游戏,输掉的人先手下一轮的游戏.问A先手,经过k轮游戏,最后胜利的人是谁. 思路: 很 ...
- 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)
萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...
- 山东第一届省赛1001 Phone Number(字典树)
Phone Number Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 We know that if a phone numb ...
随机推荐
- kaggle Cross-Validation
The Cross-Validation Procedure In cross-validation, we run our modeling process on different subsets ...
- WordCountPro小程序
WordCountPro小程序 基本任务 1.githu地址 https://github.com/JarrySmith/WordCountPro 2.psp2.1表 PSP2.1 PSP阶段 预 ...
- 树莓派(Raspberry Pi 3) centos7使用yum命令报错File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:
使用yum命令报错 File "/usr/bin/yum", line 30 except KeyboardInterrupt, e: ^SyntaxError: invalid ...
- jquery easyui datagrid 多选只能获取一条数据
DataGrid属性: singleSelect ------如果为true,则只允许选择一行: idField ------- 指明哪一个字段是标识字段: 方法: 一:getSelections-- ...
- C# Winform欢迎窗体实现()
方法一.program.cs 中先启动欢迎窗体,然后注册程序运行空闲去执行主程序窗体相应初始化代码 static void Main(string[] args) { Application.Enab ...
- 动态合并GridView数据行DataRow的列
前段时间,Insus.NET一直在演示GridView控件Header头行或列:<动态变更GridView控件列名>和<动态合并或定制GridView控件Header头某些列> ...
- spring mvc常用注解标签
@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model , ...
- Kotlin 数据类型(字符类型)
Kotlin有两种常见的字符类型. 第一种是String,第二种char. String String 的类型的赋值必须是用双引号的. 格式: var name="Arm830" ...
- JavaFx 实现画图工具
制作一款类似于Windows画图工具程序 功能需求: (1)在画布上绘制直线.曲线.矩形.椭圆等图形 (2)实现输入文字,橡皮擦 (3)可以绘制填充图形以及设置画笔的颜色和粗细 (4)实现撤销操作.保 ...
- APIO 2012 派遣(可并堆)
APIO 2012 派遣(可并堆) 给定一棵N个点的树和M,每个点有两个权值ai,bi,每次可以选择一个点x,然后在这个点的子树中选若干点(可以不选自己),使得这些点的\(\sum b_i<=M ...