Bazinga HDU - 5510 不可做的暴力
http://acm.hdu.edu.cn/showproblem.php?pid=5510
想了很久队友叫我用ufs + kmp暴力过去了。
fa[x] = y表示x是y的子串,所以只有fa[x] == x才需要kmp一次。
那么这样的话,如果全部都不互为子串的话,复杂度还是爆咋的。
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- #include <vector>
- #include <queue>
- #include <string>
- #include <stack>
- #include <map>
- #include <set>
- #include <bitset>
- #include <cstdlib>
- #include <ctime>
- #define X first
- #define Y second
- #define clr(u,v); memset(u,v,sizeof(u));
- #define in() freopen("data.txt","r",stdin);
- #define out() freopen("ans","w",stdout);
- #define Clear(Q); while (!Q.empty()) Q.pop();
- #define pb push_back
- using namespace std;
- typedef long long ll;
- typedef pair<int, int> pii;
- const ll INF = 1e17;
- const int inf = 0x3f3f3f3f;
- const int maxn = + ;
- int tonext[][maxn];
- void get_next(char sub[], int tonext[], int lensub) {
- int i = , j = ;
- tonext[] = ;
- while (i <= lensub) {
- if (j == || sub[i] == sub[j]) {
- tonext[++i] = ++j;
- } else j = tonext[j];
- }
- }
- int kmp(char str[], char sub[], int lenstr, int lensub, int tonext[]) {
- int i = , j = ;
- while (i <= lenstr) {
- if (j == || str[i] == sub[j]) {
- ++i, ++j;
- } else j = tonext[j];
- if (j == lensub + ) return true;
- }
- return false;
- }
- char str[][maxn];
- int len[];
- int f;
- int fa[maxn];
- int tofind(int u) {
- if (fa[u] == u) return u;
- else return fa[u] = tofind(fa[u]);
- }
- void tomerge(int x, int y) {
- x = tofind(x), y = tofind(y);
- fa[y] = x;
- }
- void work() {
- int n;
- scanf("%d", &n);
- for (int i = ; i <= n; ++i) {
- scanf("%s", str[i] + );
- len[i] = strlen(str[i] + );
- get_next(str[i], tonext[i], len[i]);
- fa[i] = i;
- }
- printf("Case #%d: ", ++f);
- int ans = -;
- for (int i = ; i <= n; ++i) {
- for (int j = i - ; j >= ; --j) {
- if (tofind(j) != j) continue;
- if (kmp(str[i], str[j], len[i], len[j], tonext[j])) {
- tomerge(i, j); //合并的方向,小的合并去大的
- } else {
- ans = i;
- }
- // if (kmp(str[j], str[i], len[j], len[i], tonext[i])) {
- // tomerge(j, i);
- // }
- }
- }
- printf("%d\n", ans);
- return;
- }
- int main() {
- #ifdef local
- in();
- #else
- #endif
- int t;
- scanf("%d", &t);
- while (t--) work();
- return ;
- }
有一个超时的AC自动机算法。复杂度O(T * n * lenstr * lenstr)
首先所有串buildFail
然后对于每一个串,爬Fail树。从后往前枚举
那么每个串跑一次Fail树的时候就能知道有多少个子串。成立的条件是子串个数 < i,则i位置成立。
如果后面的串使得匹配子串个数变大的话,那么是不影响的,说明在后面枚举的时候那个位置就应该是已经成立的了。
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- #include <vector>
- #include <queue>
- #include <string>
- #include <stack>
- #include <map>
- #include <set>
- #include <bitset>
- #include <cstdlib>
- #include <ctime>
- #define X first
- #define Y second
- #define clr(u,v); memset(u,v,sizeof(u));
- #define in() freopen("2.h","r",stdin);
- #define out() freopen("ans","w",stdout);
- #define Clear(Q); while (!Q.empty()) Q.pop();
- #define pb push_back
- using namespace std;
- typedef long long ll;
- typedef pair<int, int> pii;
- const ll INF = 1e17;
- const int inf = 0x3f3f3f3f;
- char str[][ + ];
- struct Node {
- int flag, id;
- struct Node *Fail;
- struct Node *pNext[];
- } tree[ + ];
- int t;
- struct Node * create() {
- struct Node * p = &tree[t++];
- p->flag = ;
- p->Fail = NULL;
- p->id = t - ;
- for (int i = ; i < ; ++i) p->pNext[i] = NULL;
- return p;
- }
- void toinsert(struct Node **T, char str[]) {
- struct Node *p = *T;
- if (p == NULL) p = *T = create();
- for (int i = ; str[i]; ++i) {
- int id = str[i] - 'a';
- if (p->pNext[id] == NULL) {
- p->pNext[id] = create();
- }
- p = p->pNext[id];
- }
- p->flag++;
- }
- struct Node * que[ + ];
- void BuildFlag(struct Node **T) {
- struct Node *p = *T;
- struct Node *root = *T;
- if (p == NULL) return ;
- int head = , tail = ;
- que[tail++] = root;
- while (head < tail) {
- p = que[head];
- for (int i = ; i < ; ++i) {
- if (p->pNext[i] != NULL) {
- if (p == root) {
- p->pNext[i]->Fail = root;
- } else {
- struct Node * FailNode = p->Fail;
- while (FailNode != NULL) {
- if (FailNode->pNext[i] != NULL) {
- p->pNext[i]->Fail = FailNode->pNext[i];
- break;
- }
- FailNode = FailNode->Fail;
- }
- }
- que[tail++] = p->pNext[i];
- } else if (p == root) {
- p->pNext[i] = root;
- } else {
- p->pNext[i] = p->Fail->pNext[i];
- }
- }
- head++;
- }
- }
- int vis[ + ], DFN;
- int searchAC(struct Node *T, char str[], int val) {
- DFN++;
- int ans = ;
- struct Node * p = T;
- struct Node * root = T;
- if (p == NULL) return ;
- for (int i = ; str[i]; ++i) {
- int id = str[i] - 'a';
- p = p->pNext[id];
- struct Node * temp = p;
- while (temp != root && vis[temp->id] != DFN) {
- vis[temp->id] = DFN;
- ans += temp->flag;
- temp = temp->Fail;
- if (ans >= val) return false;
- }
- }
- return true;
- }
- int f;
- void work() {
- t = ;
- printf("Case #%d: ", ++f);
- int n;
- scanf("%d", &n);
- struct Node * T = NULL;
- for (int i = ; i <= n; ++i) {
- scanf("%s", str[i] + );
- toinsert(&T, str[i]);
- }
- BuildFlag(&T);
- for (int i = n; i ; --i) {
- if(searchAC(T, str[i], i)) {
- printf("%d\n", i);
- return;
- }
- }
- printf("-1\n");
- return;
- }
- int main() {
- #ifdef LOCAL
- in();
- #else
- #endif
- int t;
- scanf("%d", &t);
- while (t--) work();
- return ;
- }
Bazinga HDU - 5510 不可做的暴力的更多相关文章
- Bazinga HDU 5510 Bazinga(双指针)
Bazinga HDU 5510 Bazinga(双指针) 题链 解法:对于串i来说,如果串i是不符合的,那么代表串i之前的字符串都是i的子串,那么我们求一个新的i(定义为ti),如果i是ti 的子串 ...
- Bazinga HDU - 5510【技巧暴力+字符串】
题目:https://vjudge.net/problem/HDU-5510 $2015ACM/ICPC$ 亚洲区沈阳站 题目大意: 输入$t$(表示样例个数) 如何每个样例一个 $n$,表示字符串的 ...
- 【Bazinga HDU - 5510 】【考察strstr()的使用】【贪心】
题意分析 1.题目大致说的是让你输出符合这种条件(在所给的字符串中至少有一个不是它的子串)的字符串对应的label,若没有输出-1: 2.判断子串可以用string.h下的strstr(s1, s2) ...
- hdu 5510 Bazinga(字符串kmp)
Bazinga Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- HDU 2920 分块底数优化 暴力
其实和昨天写的那道水题是一样的,注意爆LL $1<=n,k<=1e9$,$\sum\limits_{i=1}^{n}(k \mod i) = nk - \sum\limits_{i=1}^ ...
- HDU 5510 Bazinga 暴力匹配加剪枝
Bazinga Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5510 ...
- HDU 5510:Bazinga(暴力KMP)
http://acm.hdu.edu.cn/showproblem.php?pid=5510 Bazinga Problem Description Ladies and gentlemen, p ...
- hdu 5510 Bazinga (KMP+暴力标记)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510 思路: 一开始直接用KMP莽了发,超时了,后面发现如果前面的字符串被后面的字符串包含,那么我们就 ...
- hdu 5510 Bazinga(暴力)
Problem Description Ladies and gentlemen, please sit up straight. Don't tilt your head. I'm serious. ...
随机推荐
- 洛谷【P1908】逆序对
题目传送门:https://www.luogu.org/problemnew/show/P1908 所谓逆序对,就是序列中\(a[i]>a[j]\)且\(i<j\)的有序对. 所以我们在归 ...
- Fortify代码扫描解决方案
Fortify扫描漏洞解决方案: Log Forging漏洞: 1.数据从一个不可信赖的数据源进入应用程序. 在这种情况下,数据经由getParameter()到后台. 2. 数据写入到应用程序或系统 ...
- Poj 3356 ACGT(LCS 或 带备忘的递归)
题意:把一个字符串通过增.删.改三种操作变成另外一个字符串,求最少的操作数. 分析: 可以用LCS求出最大公共子序列,再把两个串中更长的那一串中不是公共子序列的部分删除. 分析可知两个字符串的距离肯定 ...
- nginx实现带参数目录域名重定向二级域名方法
本文章介绍了关于nginx实现带参数目录域名重定向二级域名方法,有需要学习的朋友可参考一下. 下面的代码是基于nginx的子目录301到其他域名(URL)的规则.作用是例如访问http://www.p ...
- RESTEasy常用注解
一.@Path,标注资源类或方法的相对路径 Path参数的形式有三种: 1.固定值 2.纯正则表达式 3.固定值和正则表达式的混 ...
- 启动新内核出现:Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
转载请注明出处:http://blog.csdn.net/qq_26093511/article/details/51841281 启动新内核出现错误:Kernel panic - not synci ...
- LAMP 1.2 Apache编译安装问题解决
这个错误安装 yum install -y gcc error: mod_deflate has been requested but can not be built due to prerequi ...
- 阶段2-新手上路\项目-移动物体监控系统\Sprint1-声音报警子系统开发\第1节-Sprint Backlog规划
根据之前的sprint1-声音报警子系统是相对比较大的一个需求,需要把它进一步细化,然后指定sprint Backlog product Backlog是整个产品的功能列表! sprint Backl ...
- JavaScript中的构造函数和工厂函数说明
在cnblog上看到一篇文章,讲解JS中的构造函数和工厂函数,觉得讲的真好 JavaScript中的工厂函数和构造函数都能用来创建一个对象,我们可以来看看下面的例子 构造函数 function cre ...
- CSS定位机制总结
1,CSS 有三种基本的定位机制:普通流.浮动和绝对定位.除非专门指定,否则所有框都在普通流中定位.2,普通流定位:块级框从上到下一个接一个地排列,框之间的垂直距离是由框的垂直外边距计算出来.行内框在 ...