luogu P2353 背单词
二次联通门 : luogu P2353 背单词
一眼看过去, 卧槽,AC自动机板子题
写完后T成SB
卧槽10^6 做个篮子啊
重构思路。。。
恩。。Hash + 莫队。。。
恶心啊。。
找xxy dalao, AC自动机 + 前缀和
码完WA成SB
去群里找dalao
大佬告诉了我前缀和的正确使用姿势。。。
然后就依然WA成SB
做个毛线
贴一个AC自动机的30代码
#include <cstdio>
#include <cstring>
#include <queue> #define Max 3000090 void read (int &now)
{
now = ;
register char word = getchar ();
while (word < '' || word > '')
word = getchar ();
while (word >= '' && word <= '')
{
now = now * + word - '';
word = getchar ();
}
} char __txt[Max]; struct T_D
{
T_D *child[]; T_D *Fail;
int Count; int number;
T_D ()
{
for (int i = ; i < ; i ++)
this->child[i] = NULL; Count = ;
Fail = NULL;
number = ;
}
}; int List[Max << ];
int List_Cur; bool visit[Max]; class AC_Type
{ private : T_D *Root;
int Trie_Count; public : void Insert (char *key)
{
T_D *now = Root; int Len = strlen (key);
int Id; for (int i = ; i < Len; i ++)
{
Id = key[i] - 'a';
if (now->child[Id] == NULL)
{
now->child[Id] = new T_D;
now->child[Id]->number = ++ Trie_Count;
} now = now->child[Id];
}
now->Count ++;
} AC_Type ()
{
Trie_Count = ;
Root = new T_D ;
Root->number = ++ Trie_Count;
} void Build_AC ()
{
std :: queue <T_D *> Queue; Queue.push (Root); T_D *now, *pos;
while (!Queue.empty ())
{
now = Queue.front ();
Queue.pop (); pos = NULL; for (int i = ; i < ; i ++)
{
if (now->child[i] == NULL)
continue;
if (now == Root)
now->child[i]->Fail = Root;
else
{
for (pos = now->Fail; pos; pos = pos->Fail)
if (pos->child[i])
{
now->child[i]->Fail = pos->child[i];
break;
}
if (pos == NULL)
now->child[i]->Fail = Root;
}
Queue.push (now->child[i]);
}
}
} int Query (int x, int y)
{
T_D *now, *pos; int Id ;
now = Root;
int res = ; for (int i = x; i <= y; i ++)
{
Id = __txt[i] - 'a';
for (; now != Root && now->child[Id] == NULL; now = now->Fail); now = now->child[Id];
if (now == NULL)
now = Root; for (pos = now; pos != Root && !visit[pos->number]; pos = pos->Fail)
{
res += pos->Count;
visit[pos->number] = true;
List[++ List_Cur] = pos->number;
} for (int j = ; j <= List_Cur; j ++)
visit[List[j]] = false; List_Cur = ; } return res;
} }; AC_Type Make; int N, Q;
char line[Max]; int main (int argc, char *argv[])
{
read (N);
read (Q);
scanf ("%s", __txt); for (int i = ; i <= N; i ++)
{
scanf ("%s", line);
Make.Insert (line);
} Make.Build_AC (); for (int x, y; Q --; )
{
read (x);
read (y); printf ("%d\n", Make.Query (-- x, -- y));
} return ;
}
再贴个AC自动机思路正确但由于细节问题WA成dog的代码
#include <cstdio>
#include <cstring>
#include <queue> #define Max 1000090 #define DEBUG for (int i = 1; i <= strlen (__txt); i ++)\
printf ("%d ", __sum[i]);\
putchar ('\n'); void read (int &now)
{
now = ;
register char word = getchar ();
while (word < '' || word > '')
word = getchar ();
while (word >= '' && word <= '')
{
now = now * + word - '';
word = getchar ();
}
} char __txt[Max]; struct T_D
{
T_D *child[]; T_D *Fail;
int Count; int number;
T_D ()
{
for (int i = ; i < ; i ++)
this->child[i] = NULL; Count = ;
Fail = NULL;
number = ;
}
}; int __sum[Max]; class AC_Type
{ private : T_D *Root;
int Trie_Count; public : void Insert (char *key)
{
T_D *now = Root; int Len = strlen (key);
int Id; for (register int i = ; i < Len; i ++)
{
Id = key[i] - 'a';
if (now->child[Id] == NULL)
{
now->child[Id] = new T_D;
now->child[Id]->number = ++ Trie_Count;
} now = now->child[Id];
}
now->Count ++;
} AC_Type ()
{
Trie_Count = ;
Root = new T_D ;
Root->number = ++ Trie_Count;
} void Build_AC ()
{
std :: queue <T_D *> Queue; Queue.push (Root); T_D *now, *pos;
while (!Queue.empty ())
{
now = Queue.front ();
Queue.pop (); pos = NULL; for (register int i = ; i < ; i ++)
{
if (now->child[i] == NULL)
continue;
if (now == Root)
now->child[i]->Fail = Root;
else
{
for (pos = now->Fail; pos; pos = pos->Fail)
if (pos->child[i])
{
now->child[i]->Fail = pos->child[i];
break;
}
if (pos == NULL)
now->child[i]->Fail = Root;
}
Queue.push (now->child[i]);
}
}
} int Query ()
{
T_D *now, *pos; int Id ;
now = Root;
int res = ;
int Len = strlen (__txt); for (register int i = ; i < Len; i ++)
{
Id = __txt[i] - 'a';
for ( ; now != Root && now->child[Id] == NULL; now = now->Fail); now = now->child[Id];
if (now == NULL)
now = Root; for (pos = now; pos != Root && pos->Count >= ; pos = pos->Fail)
{
__sum[i + ] += pos->Count;
pos->Count = -;
}
__sum[i + ] += __sum[i]; } return res;
} }; AC_Type Make; int N, Q;
char line[Max]; int length[Max]; int main (int argc, char *argv[])
{ read (N);
read (Q);
scanf ("%s", __txt); for (int i = ; i <= N; i ++)
{
scanf ("%s", line);
Make.Insert (line);
length[i] = strlen (line);
} Make.Build_AC ();
Make.Query ();
register int Answer, now; for (int x, y; Q --; )
{
Answer = ; read (x);
read (y); for (int i = ; i <= N; i ++)
Answer += (__sum[y - length[i]] - __sum[x - ]); printf ("%d\n", Answer);
} return ;
}
最后再贴个正解。。。。是我想麻烦了。。kmp或者hash都可以。。
/*
luogu P2353 背单词 由于M很小
可以进行M次kmp 统计出M个前缀和 每次输出时把 M 个前缀和扫一遍
注意区间的开闭问题 由于r端点的串不包含在所查询的区间内
所以要减去当前模式串的长度 */
#include <cstdio>
#include <cstring> #define Max 1000090 void read (int &now)
{
now = ;
register char word = getchar ();
while (word > '' || word < '')
word = getchar ();
while (word >= '' && word <= '')
{
now = now * + word - '';
word = getchar ();
}
} int __next[Max]; void Get_Next (char *line)
{
__next[] = -; for (int pos_1 = , pos_2 = -, Len = strlen (line); pos_1 < Len; )
if (pos_2 == - || line[pos_1] == line[pos_2])
{
pos_1 ++;
pos_2 ++;
__next[pos_1] = pos_2;
}
else
pos_2 = __next[pos_2]; } int __sum[Max][Max / + ]; void Kmp (char *line, char *__txt, int number)
{
for (int Len_txt = strlen (__txt), Len = strlen (line), pos_1 = , pos_2 = ; pos_1 <= Len_txt; )
{
if (pos_2 == - || __txt[pos_1] == line[pos_2])
{
pos_1 ++;
pos_2 ++;
}
else
pos_2 = __next[pos_2];
if (pos_2 == Len)
{
__sum[pos_1][number] ++;
pos_2 = __next[pos_2];
}
}
} char __txt[Max]; int length[Max];
char line[Max]; int main (int argc, char *argv[])
{
int N, M; read (N);
read (M); scanf ("%s", __txt); int Len_txt = strlen (__txt); for (int i = ; i <= N; i ++)
{
scanf ("%s", line); Get_Next (line);
Kmp (line, __txt, i); length[i] = strlen (line);
} for (int i = ; i <= Len_txt; i ++) // 把每个模式串的前缀和分开存
for (int j = ; j <= N; j ++)
__sum[i][j] += __sum[i - ][j]; for (int i = , x, y, Answer; i <= M; i ++)
{
read (x);
read (y);
Answer = ; for (int j = ; j <= N; j ++)
if (x - <= y - length[j])
Answer += __sum[y][j] - __sum[x + length[j] - ][j]; printf ("%d\n", Answer);
}
return ;
}
luogu P2353 背单词的更多相关文章
- 洛谷 P2353 背单词
题目背景 小明对英语一窍不通,令老师十分头疼.于是期末考试前夕,小明被逼着开始背单词…… 题目描述 老师给了小明一篇长度为N的英语文章,然后让小明背M个单词.为了确保小明不会在背单词时睡着,老师会向他 ...
- AC日记——背单词 洛谷 P2353
背单词 思路: KMP+统计前缀和优化: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1000005 ], ...
- [SCOI2016]背单词——trie树相关
题目描述 Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的: ...
- [SCOI2016]背单词 题解
背单词 https://www.luogu.com.cn/problem/P3294 前言: Trie树的省选题(瑟瑟发抖QAQ) 问题汇总:(请忽略) (1)对Trie字典树的运用不熟练 (2)没想 ...
- 做中学(Learning by Doing)之背单词-扇贝网推荐
做中学(Learning by Doing)之背单词-扇贝网推荐 看完杨贵福老师(博客,知乎专栏,豆瓣)的「继续背单词,8个月过去了」,我就有写这篇文章的冲动了,杨老师说: 有时候我会感觉非常后悔,如 ...
- “我爱背单词”beta版发布与使用说明
我爱背单词BETA版本发布 第二轮迭代终于画上圆满句号,我们的“我爱背单词”beta版本已经发布. Beta版本说明 项目名称 我爱背单词 版本 Beta版 团队名称 北京航空航天大学计算机学院 拒 ...
- BZOJ4567[Scoi2016]背单词
4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 304 Solved: 114 [Submit][Status] ...
- 《我爱背单词》 Alpha版 发布说明
——发布地址(baidu网盘) http://pan.baidu.com/s/15omtB ——简介 <我爱背单词>是一款英语单词记忆和管理辅助软件,旨在帮助广大考生在短期内攻克GRE. ...
- [No000057]一个人默默背单词,小心被传染哦
不日凛冬将至,全国各地,已有多名少侠因季节变化,出现了不同程度的四肢不勤.bd不分的症状.具体表现为—— 包大人在此高能预警:不想背单词,有可能你已经被传染了. 好好的,怎么突然不想背单词了 哈佛医学 ...
随机推荐
- 记录一次使用NPOI遇到的问题
在.net 下一般使用NPOI操作Excel相信大家都不陌生,但是本人在操作过程中遇到一个比较奇怪的问题,特写此博客记录与大家分享. 例子是使用Winform,点击按钮时弹出打开文件对话框,然后选择文 ...
- 网络编程之基于UDP协议的套接字编程、基于socketserver实现并发的socket
目录 基于UDP协议的套接字编程 UDP套接字简单示例 服务端 客户端 基于socketserver实现并发的socket 基于TCP协议 server类 request类 继承关系 服务端 客户端1 ...
- CSS揭秘-半透明边框与多重边框
场景一: 实现半透明边框: 由于CSS样式的默认行为,背景色的渲染范围是 content+padding+border. 半透明边框被主调色影响, 实现的效果为 解决方案: 使用backgroun ...
- consul:架构
官方文档:https://www.consul.io/docs/internals/architecture.html
- python实现系统调用cmd命令的模块---subprocess模块
如果要python实现系统命令或者调用脚本,python中可以利用os或者subprocess模块实现: 一.os模块: # coding:utf-8 command = os.system('net ...
- Linux普通用户登录后,命令行提示:-bash-4.1$ ,原因分析及解决
原文 有时候在使用用户登陆Linux系统时会发现,命令行提示符成了:-bash-4.1$,不显示用户名,路径信息. 原因:用户家目录里面与环境变量有关的文件被删除所导致的 也就是这俩文件:.bash_ ...
- JAVA Coder 的《深入分析Java Web 技术内幕》读书笔记
本文基于<深入分析Java Web 技术内幕> <深入分析Java Web 技术内幕>,作者是 许令波,电子工业出版社.本文只是记录书本当中的精彩部分,作个人回顾和技术分享,请 ...
- 国内不fq安装K8S一: 安装docker
目录 1.安装docker 1.1 准备工作 1.2 安装docker 1.3 修改cgroup 国内不fq安装K8S一: 安装docker 国内不fq安装K8S二: 安装kubernet 国内不fq ...
- spring data jpa 表关联设置用户表关联角色表配置
User 表: @ManyToMany(cascade = { CascadeType.MERGE }) @JsonIgnore @JoinTable(name = "UserRole&qu ...
- phpstorm webstorm编辑器正则替换 类名,方法名替换
首先勾选Match Case 和 Regex 正则规则:无须添加//左右分解符,直接写正则表达式,注意应该转义的部分,需要原封不动替换的部分加上括号 替换规则:正常书写正则,要继承下来的字符使用$1. ...