HDU
来源:互联网 发布:搭建局域网网络硬盘 编辑:程序博客网 时间:2024/06/05 20:30
传送门:点击打开链接
一个长度为lent的串T最多可以构造出lent个数字,所以这道题目的难点在于如何快速的将构造出的数字和原数字进行比较。
将两个T串合并成一个大的S串,构造出的数字实际上就是S的每一个后缀的前lent个字符。如何比较呢?如果S中从第i个位置开始的一个后缀和T的最长公共前缀k >= lent,那么这两个数字相等,如果k < lent,我们通过比较S[i + k]和T[k]的值来确定大小关系,这样一来比较的复杂度就是O(1)。
通过叙述,很容易就知道要用到拓展KMP算法啦。
此外要注意如果串T是有循环节的话(如abcabc),构造出来的数字会重复lent / 循环节长度次。
用KMP算法求出循环节长度即可。
代码如下:
#include <bits/stdc++.h>using namespace std;const int N = 2000005;char S[N], T[N];int lens, lent;int Next[N];int extend[N];void GetNext(){ int a = 0; Next[0] = lent; while (a < lent - 1 && T[a] == T[a + 1]) a++; Next[1] = a; a = 1; for (int i = 2; i < lent; i++) { int p = a + Next[a] - 1; int t = Next[i - a]; if (i + t - 1 >= p) { int j = max(p - i + 1, 0); while (i + j < lent && T[i + j] == T[j]) j++; Next[i] = j; a = i; } else Next[i] = t; }}void GetExtend(){ GetNext(); int a = 0; while (a < lens && a < lent && S[a] == T[a]) a++; extend[0] = a; a = 0; for (int i = 1; i < lens; i++) { int p = a + extend[a] - 1; int t = Next[i - a]; if (i + t - 1 >= p) { int j = max(p - i + 1, 0); while (i + j < lens && S[i + j] == T[j]) j++; extend[i] = j; a = i; } else extend[i] = t; }}void GetKmpNext(){ int i = 0; int k = -1; Next[0] = -1; while (i < lent) if (k == -1 || T[i] == T[k]) Next[++i] = ++k; else k = Next[k];}int main(){ //freopen("test.txt", "r", stdin); //freopen("out.txt", "w", stdout); int t, Case = 1; scanf("%d", &t); while (t--) { scanf("%s", T); strcpy(S, T); lent = strlen(T); for (int i = lent; i < 2 * lent; i++) S[i] = T[i - lent]; lens = 2 * lent; GetExtend(); int ans1 = 0, ans2 = 0, ans3 = 0; for (int i = 0; i < lent; i++) { if (extend[i] >= lent) ans2++; else if (S[i + extend[i]] > T[extend[i]]) ans3++; else ans1++; } int tmp = 1; GetKmpNext(); if (lent % (lent - Next[lent]) == 0) tmp = lent / (lent - Next[lent]); printf("Case %d: %d %d %d\n", Case++, ans1 / tmp, ans2 / tmp, ans3 / tmp); } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- 值传递引用传递(java)
- #coding=utf-8的作用 还是乱码
- 【洛谷3834】 【模板】可持久化线段树 (主席树)
- /etc/profile,/etc/bashrc,~/.bash_profile,~/.bashrc,~/.bash_logout的区别
- js复习笔记day7
- HDU
- 数据包络分析法(DEA)在数学建模中的应用
- canvas标签的用法
- 排列和组合简单的递归思路以及C++实现
- PAT A 1095. Cars on Campus (30)
- vue 绑定单值和双向绑定
- Linux中使用gzip来压缩/解压 *.gz文件
- [第八季]1.Java Web开发概述开发环境及一个简单案例(一)
- win7激活那点事: