题目大意:输入$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. 2017年PHP程序员未来路在何方?(转载)

    PHP 从诞生到现在已经有 20 多年历史,从 Web 时代兴起到移动互联网退潮,互联网领域各种编程语言和技术层出不穷, Node.js . GO . Python 不断地在挑战 PHP 的地位.这些 ...

  2. emlog博客插件分享openSug

    emlog博客插件百度搜索下拉提示框openSug.js发布上线啦: 下载:https://www.opensug.org/faq/.../opensug.emlog_v1.0.0.zip[~4KB]

  3. 008---re正则模块

    re正则模块 字符串的匹配规则 匹配模式 re.match() re.search() re.findall() re.split() re.sub() 元字符 print('------------ ...

  4. 最短路径算法 4.SPFA算法(1)

    今天所说的就是常用的解决最短路径问题最后一个算法,这个算法同样是求连通图中单源点到其他结点的最短路径,功能和Bellman-Ford算法大致相同,可以求有负权的边的图,但不能出现负回路.但是SPFA算 ...

  5. 数列分块入门 1 LOJ6277

    题目描述 给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 n. 第二行输入 n 个数字,第 iii 个数字为 a​i​​,以空格隔开. 接下来输 ...

  6. React实现最完整的百度搜索框

    import React,{Component} from 'react' import ReactDOM,{render} from 'react-dom' import 'bootstrap/di ...

  7. facebook hash key

    private void printHashKey() { try { PackageInfo info = getPackageManager().getPackageInfo( "xxx ...

  8. 在Android上,怎样与Kotlin一起使用Retrofit(KAD21)

    作者:Antonio Leiva 时间:Apr 18, 2017 原文链接:https://antonioleiva.com/retrofit-android-kotlin/ 这是又一个例子,关于怎样 ...

  9. 10-Mysql数据库----数据的增删改

    本节重点: 插入数据 INSERT 更新数据 UPDATE 删除数据 DELETE 再来回顾一下之前我们练过的一些操作,相信大家都对插入数据.更新数据.删除数据有了全面的认识.那么在mysql中其实最 ...

  10. GraphSAGE 代码解析(二) - layers.py

    原创文章-转载请注明出处哦.其他部分内容参见以下链接- GraphSAGE 代码解析(一) - unsupervised_train.py GraphSAGE 代码解析(三) - aggregator ...