二次联通门 : 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 背单词的更多相关文章

  1. 洛谷 P2353 背单词

    题目背景 小明对英语一窍不通,令老师十分头疼.于是期末考试前夕,小明被逼着开始背单词…… 题目描述 老师给了小明一篇长度为N的英语文章,然后让小明背M个单词.为了确保小明不会在背单词时睡着,老师会向他 ...

  2. AC日记——背单词 洛谷 P2353

    背单词 思路: KMP+统计前缀和优化: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1000005 ], ...

  3. [SCOI2016]背单词——trie树相关

    题目描述 Lweb 面对如山的英语单词,陷入了深深的沉思,”我怎么样才能快点学完,然后去玩三国杀呢?“.这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的: ...

  4. [SCOI2016]背单词 题解

    背单词 https://www.luogu.com.cn/problem/P3294 前言: Trie树的省选题(瑟瑟发抖QAQ) 问题汇总:(请忽略) (1)对Trie字典树的运用不熟练 (2)没想 ...

  5. 做中学(Learning by Doing)之背单词-扇贝网推荐

    做中学(Learning by Doing)之背单词-扇贝网推荐 看完杨贵福老师(博客,知乎专栏,豆瓣)的「继续背单词,8个月过去了」,我就有写这篇文章的冲动了,杨老师说: 有时候我会感觉非常后悔,如 ...

  6. “我爱背单词”beta版发布与使用说明

    我爱背单词BETA版本发布 第二轮迭代终于画上圆满句号,我们的“我爱背单词”beta版本已经发布. Beta版本说明 项目名称 我爱背单词 版本 Beta版 团队名称 北京航空航天大学计算机学院  拒 ...

  7. BZOJ4567[Scoi2016]背单词

    4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 304 Solved: 114 [Submit][Status] ...

  8. 《我爱背单词》 Alpha版 发布说明

    ——发布地址(baidu网盘) http://pan.baidu.com/s/15omtB ——简介  <我爱背单词>是一款英语单词记忆和管理辅助软件,旨在帮助广大考生在短期内攻克GRE. ...

  9. [No000057]一个人默默背单词,小心被传染哦

    不日凛冬将至,全国各地,已有多名少侠因季节变化,出现了不同程度的四肢不勤.bd不分的症状.具体表现为—— 包大人在此高能预警:不想背单词,有可能你已经被传染了. 好好的,怎么突然不想背单词了 哈佛医学 ...

随机推荐

  1. Scala 系列(十一)—— 模式匹配

    一.模式匹配 Scala 支持模式匹配机制,可以代替 swith 语句.执行类型检查.以及支持析构表达式等. 1.1 更好的swith Scala 不支持 swith,可以使用模式匹配 match.. ...

  2. 一个简单便捷的树形显示Ztree

    这是本人在闲时研究的一个用于显示树形列表的小玩意. zTree 是一个依靠 jQuery 实现的多功能 “树插件”.优异的性能.灵活的配置.多种功能的组合是 zTree 最大优点. 下面就说说怎么用吧 ...

  3. Golang逃逸分析

    Golang逃逸分析 介绍逃逸分析的概念,go怎么开启逃逸分析的log. 以下资料来自互联网,有错误之处,请一定告之. sheepbao 2017.06.10 什么是逃逸分析 wiki上的定义 In ...

  4. .NET中的异步编程——动机和单元测试

    背景 自.NET 4.5发布以来已经有很长一段时间了.留在了我们的记忆里,其发布在2012年8月15日.是的,六年前.感觉老了吗?好吧,我不打算让你做出改变,而是提醒你一些.NET发布的亮点.此版本带 ...

  5. 理解 BLS 签名算法

    理解 BLS 签名算法 来源 https://medium.com/cryptoadvance/bls-signatures-better-than-schnorr-5a7fe30ea716 原文标题 ...

  6. Django---图书管理系统,一对多(外键设置),__str__和__repr__的区别,进阶版项目说明简介.模版语言if ... else ..endif

    Django---图书管理系统,一对多(外键设置),__str__和__repr__的区别,进阶版项目说明简介.模版语言if ... else ..endif 一丶__str__ 和 __repr__ ...

  7. 全程实操cdh5.14.4中集成安装kylin2.4.1与使用测试

    在cdh5.14.4安装完成并排错完成的情况下,进行如下kylin安装操作: 1.实验环境 三台CentOS 7主机,IP地址 192.168.43.129 cm1 192.168.43.130 cm ...

  8. Scheduling Tasks

    官方文档 https://spring.io/guides/gs/scheduling-tasks/ 官方文档详细介绍了@Scheduled中fixedRate,fixedDelay,cron的用法 ...

  9. 关于DataX

    1. 关于DataX 1.1. 前言 为什么写这篇文章,因为初出茅庐的时候,曾经遇到的一个面试官就是DataX的作者之一,而当时我还偏偏因为业务需求做了个数据库的同步工具,我当时不知道他做过这么专业的 ...

  10. 解决bootstrap模态框居中问题

    完美解决办法: 在bootstrap.js或bootstrap.min.js文件中找到Modal.prototype.show方法. 在that.$element.addClass('in').att ...