题目大意:输入$n$个正整数,($1\leq n\leq 10000$),要求输出最长的连号的长度。(连号指从小到大连续自然数)

题解:考虑从小到大连续自然数差分为$1$,所以可以把原数列差分(后缀自动机不怎么会写啊),查询串为$1,11,111,\dots,111\dots(n-1个1)$,把它们插入到$AC$自动机中,然后查询即可,原数列差分不为$0,1$时赋为$0$(因为不对答案有影响)

卡点:1.原序列差分的数不为$0,1$时会挂。。。

C++ Code:($AC$自动机2018-8-13)

#include <cstdio>
#include <queue>
#define maxn 10010
using namespace std;
int n;
int s[maxn], a[maxn], b[maxn];
int nxt[maxn][2], fail[maxn], cnt[maxn], tot;
int root = 0;
queue<int> q;
void add(int *s, int n) {
int now = root, len = n;
for (int i = 1; i <= len; i++) {
if (nxt[now][s[i]]) now = nxt[now][s[i]];
else now = nxt[now][s[i]] = ++tot;
cnt[now]++;
}
}
void build() {
for (int i = 0; i < 2; i++)
if (nxt[root][i]) fail[nxt[root][i]] = root, q.push(nxt[root][i]);
while (!q.empty()) {
int x = q.front(); q.pop();
for (int i = 0; i < 2; i++) {
if (nxt[x][i]) fail[nxt[x][i]] = nxt[fail[x]][i], q.push(nxt[x][i]);
else nxt[x][i] = nxt[fail[x]][i];
}
}
}
int ask(int *s, int n) {
int now = root, ans = 0, len = n;
for (int i = 1; i <= n; i++) {
if (s[i] > 1 || s[i] < 0) s[i] = 0;
now = nxt[now][s[i]];
for (int j = now; j && ~cnt[j]; j = fail[j]) ans += cnt[j], cnt[j] = -1;
}
return ans;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &s[i]), b[i] = 1;
for (int i = 2; i <= n; i++) a[i - 1] = s[i] - s[i - 1];
add(b, n - 1);
build();
printf("%d\n", ask(a, n - 1) + 1);
return 0;
}

  

题解:当然我们也可以用后缀自动机来做,对差分串建一个后缀自动机,发现若答案长度为$len$,那么长度为$len-1$也是答案,所以可以二分答案(如果你直接求最长的$1$的字段也可以,但我就得这样不是很优美有趣)。

卡点:

C++ Code:

#include <cstdio>
#include <cstring>
#define maxn 20010
using namespace std;
int nxt[maxn][2], fail[maxn], R[maxn], idx;
int last, now, np, p, t, root;
int n, a[maxn];
void insert(int x) {
if (x < 0 || x > 1) x = 0;
R[now = ++idx] = R[p = last] + 1; last = now;
for (; ~p && !nxt[p][x]; p = fail[p]) nxt[p][x] = now;
if (!~p) {fail[now] = root; return ;}
if (R[t = nxt[p][x]] == R[p] + 1) {fail[now] = t; return ;}
R[np = ++idx] = R[p] + 1;
for (int i = 0; i < 2; i++) nxt[np][i] = nxt[t][i];
fail[np] = fail[t]; fail[t] = fail[now] = np;
for (; nxt[p][x] == t; p = fail[p]) nxt[p][x] = np;
}
int tmp[maxn];
bool check(int mid) {
for (int i = 1; i <= mid; i++) tmp[i] = 1;
int now = root;
for (int i = 1; i <= mid; i++) {
now = nxt[now][tmp[i]];
if (!now) return false;
}
return true;
}
int main() {
scanf("%d", &n);
fail[root = 0] = -1; idx = last = 1;
scanf("%d", &a[1]);
for (int i = 2; i <= n; i++) {
scanf("%d", &a[i]);
insert(a[i] - a[i - 1]);
}
int l = 0, r = n, ans = 0;
while (l <= r) {
int mid = l + r >> 1;
if (check(mid)) {
l = mid + 1;
ans = mid;
} else r = mid - 1;
}
printf("%d\n", ans + 1);
}

  

[洛谷P1420]最长连号的更多相关文章

  1. 洛谷 P1420 最长连号【最长合法子序列/断则归一】

    题目描述 输入n个正整数,(1<=n<=10000),要求输出最长的连号的长度.(连号指从小到大连续自然数) 输入输出格式 输入格式: 第一行,一个数n; 第二行,n个正整数,之间用空格隔 ...

  2. 洛谷P1420 最长连号 题解

    题目传送门 这道题我是打暴力的...(尴尬) 所以直接是O(N2)的时间,但好像没有炸,数据很水... #include<bits/stdc++.h> using namespace st ...

  3. P1420 最长连号

    洛谷——P1420 最长连号 题目描述 输入n个正整数,(1<=n<=10000),要求输出最长的连号的长度.(连号指从小到大连续自然数) 输入输出格式 输入格式: 第一行,一个数n; 第 ...

  4. 【洛谷】 P1420 最长连号

    题目描述 输入n个正整数,(1<=n<=10000),要求输出最长的连号的长度.(连号指从小到大连续自然数) 输入输出格式 输入格式: 第一行,一个数n; 第二行,n个正整数,之间用空格隔 ...

  5. 洛谷P1470 最长前缀

    P1470 最长前缀 Longest Prefix 题目描述 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 ...

  6. 洛谷P1470 最长前缀 Longest Prefix

    P1470 最长前缀 Longest Prefix 73通过 236提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 求大神指导,为何错? 题目描述 在生 ...

  7. 洛谷 [p1439] 最长公共子序列 (NlogN)

    可以发现只有当两个序列中都没有重复元素时(1-n的排列)此种优化才是高效的,不然可能很不稳定. 求a[] 与b[]中的LCS 通过记录lis[i]表示a[i]在b[]中的位置,将LCS问题转化为最长上 ...

  8. 洛谷.T22136.最长不下降子序列(01归并排序 分治)

    题目链接 \(Description\) 给定一个长为n的序列,每次可以反转 \([l,r]\) 区间,代价为 \(r-l+1\).要求在\(4*10^6\)代价内使其LIS长度最长,并输出需要操作的 ...

  9. 洛谷P2766 最长递增子序列问题

    https://www.luogu.org/problemnew/show/P2766 注:题目描述有误,本题求的是最长不下降子序列 方案无限多时输出 n 网络流求方案数,长见识了 第一问: DP 同 ...

随机推荐

  1. 理解HBase

    1.HBase HBase: Hadoop Database,根据Google的Big Table设计 HBase是一个分布式.面向列族的开源数据库.HDFS为Hbase提供了底层的数据存储服务,Ma ...

  2. Hadoop(23)-Yarn资源调度器

    Yarn是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台,而MapReduce等运算程序则相当于运行于操作系统之上的应用程序 1. Yarn工作机制 机制详解 第1 ...

  3. python学习——装饰器函数

    一.装饰器函数的作用是什么 答:装饰器函数是在不修改原函数及其调用方式的情况下对原函数功能进行扩展 对于搞python开发的人来说,函数占据了至关重要的地位.都说学好函数你就可以去找工作了,好了,假如 ...

  4. django之单表查询

    一.创建表 1.创建模型: 创建名为book的app,在book下的models.py中创建模型: from django.db import models # Create your models ...

  5. 最新cloudera大数据培训班 ccah ccdh 数据分析师 数据科学家

      上海2月21-24日Cloudera Developer training for Spark and Hadoop(CCA-175)北京2月23-26日Cloudera Developer tr ...

  6. Apache 服务器性能评估

    1 查看当前并发连接数 netstat -an | grep ESTABLISHED | wc -l 2 查看当前进程数 ps aux|grep httpd|wc -l

  7. request.getparameter() 获取中文出现乱码 问题

    http请求是以ISO-8859-1的编码来传送url的 如果页面的content-type为utf-8,那么在发送请求时,会将字符转成utf-8后进行传送 如: 中 的UTF-8编码为:E4 B8 ...

  8. log报错: Caused by: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.

    报错: 解决方式: 1.登录数据库查看错误原因 结果发现账号无法正常登录出现账号被锁定的错误. 2.如何账号解锁? 用sys系统管理员账号登录数据库 SQL> alter user 用户名 ac ...

  9. 「暑期训练」「Brute Force」 Optimal Point on a Line (Educational Codeforces Round 16, B)

    题意 You are given n points on a line with their coordinates $x_i$. Find the point x so the sum of dis ...

  10. C++ STL容器——stack用法介绍

    stack是一种容器适配器,专门设计用于在LIFO上下文中操作(后进先出),其中元素仅从容器的一端插入和删除. 容器适配器,而不是一种容器. 它是容器适配器是指,只要支持一系列方法的容器(empty, ...