Educational Codeforces Round 41 (Rated for Div. 2) F. k-substrings
4 seconds
256 megabytes
standard input
standard output
You are given a string s consisting of n lowercase Latin letters.
Let's denote k-substring of s as a string subsk = sksk + 1..sn + 1 - k. Obviously, subs1 = s, and there are exactly such substrings.
Let's call some string t an odd proper suprefix of a string T iff the following conditions are met:
- |T| > |t|;
- |t| is an odd number;
- t is simultaneously a prefix and a suffix of T.
For evey k-substring () of s you have to calculate the maximum length of its odd proper suprefix.
The first line contains one integer n (2 ≤ n ≤ 106) — the length s.
The second line contains the string s consisting of n lowercase Latin letters.
Print integers. i-th of them should be equal to maximum length of an odd proper suprefix of i-substring of s (or - 1, if there is no such string that is an odd proper suprefix of i-substring).
15bcabcabcabcabca
9 7 5 3 1 -1 -1 -1
24abaaabaaaabaaabaaaabaaab
15 13 11 9 7 5 3 1 1 -1 -1 1
19cabcabbcabcabbcabca
5 3 1 -1 -1 1 1 -1 -1 -1
The answer for first sample test is folowing:
- 1-substring: bcabcabcabcabca
- 2-substring: cabcabcabcabc
- 3-substring: abcabcabcab
- 4-substring: bcabcabca
- 5-substring: cabcabc
- 6-substring: abcab
- 7-substring: bca
- 8-substring: c
思路一:考虑用hash值判断字符串等价性。对于每个查询点,我们正常二分长度是不满足单调性的;于是我们转换思路,不对单点二分,而是对于每个固定的答案中心点,因为其对称的另外的点是固定的,因此可以二分求出最大匹配长度,如对于mi,最大匹配长度是2 * x + 1,则更新ans[mi - x] = max(ans[mi - x], 2 * x + 1)。这样枚举完中间点之后,我们并没有做完,因为我们只更新了每个中心点最大匹配长度对应的起点的答案,但相同的中心点,也可能作为其他起点取到最大值的中心点,因此对于每个ans[i],先将其赋为max(ans[i], ans[i - 1] - 2)。这样扫一遍ans数组就行了。瓶颈在于预处理,nlogn。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 const int B = 131; 36 37 int n; 38 char s[1000015]; 39 ll Hash[1000015], pp[1000015]; 40 ll get_Hash(int s, int e) { 41 ll res = (Hash[e] - pp[e - s + 1] * Hash[s - 1]) % MOD; 42 if (res < 0) res += MOD; 43 return res; 44 } 45 int ans[1000015]; 46 bool check(int mi, int x) { 47 return get_Hash(mi - x + 1, mi + x - 1) == get_Hash(n + 1 - mi - x + 1, n + 1 - mi + x - 1); 48 } 49 int main() { 50 scanf("%d %s", &n, s + 1); 51 pp[0] = 1; 52 for (int i = 1; i <= n; ++i) { 53 Hash[i] = (Hash[i - 1] * B + s[i]) % MOD; 54 pp[i] = pp[i - 1] * B % MOD; 55 } 56 clr(ans, -1); 57 for (int i = 1; i <= n + 1 >> 1; ++i) { 58 int s = 1, e = i, mi, res = 0; 59 if (2 * i == n + 1) break; 60 while (s <= e) { 61 mi = s + e >> 1; 62 if (check(i, mi)) s = (res = mi) + 1; 63 else e = mi - 1; 64 } 65 ans[i - res + 1] = max(ans[i - res + 1], 2 * res - 1); 66 } 67 for (int i = 1; i <= n + 1 >> 1; ++i) { 68 ans[i] = max(ans[i - 1] - 2, ans[i]); 69 printf("%d ", ans[i]); 70 } 71 return 0; 72 }
View Code
思路二:我们注意到性质ans[i] >= ans[i - 1] + 2, 也就是ans[i - 1] <= ans[i] - 2.因此我们从后往前扫ans数组,每个点从ans[i] - 2暴力向下枚举,找到答案就是最终解,并马上break。这样总体的步幅顶多n + 2 * n。复杂度O(n)。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 const int B = 131; 36 37 int n; 38 char s[1000015]; 39 ll Hash[1000015], pp[1000015]; 40 ll get_Hash(int s, int e) { 41 ll res = (Hash[e] - pp[e - s + 1] * Hash[s - 1]) % MOD; 42 if (res < 0) res += MOD; 43 return res; 44 } 45 int ans[1000015]; 46 bool check(int mi, int x) { 47 return get_Hash(mi - x + 1, mi + x - 1) == get_Hash(n + 1 - mi - x + 1, n + 1 - mi + x - 1); 48 } 49 int main() { 50 scanf("%d %s", &n, s + 1); 51 pp[0] = 1; 52 for (int i = 1; i <= n; ++i) { 53 Hash[i] = (Hash[i - 1] * B + s[i]) % MOD; 54 pp[i] = pp[i - 1] * B % MOD; 55 } 56 clr(ans, -1); 57 for (int i = n + 1 >> 1; i; --i) { 58 int l = i, r = n + 1 - i; 59 if (l == r) { 60 ans[i] = -1; 61 continue; 62 } 63 for (int j = ans[i + 1] + 2; ~j; j -= 2) { 64 if (get_Hash(l, l + j - 1) == get_Hash(r - j + 1, r)) { 65 ans[i] = j; 66 break; 67 } 68 } 69 } 70 for (int i = 1; i <= n + 1 >> 1; ++i) { 71 printf("%d ", ans[i]); 72 } 73 return 0; 74 }
View Code
转载于:https://www.cnblogs.com/BIGTOM/p/9146337.html
Educational Codeforces Round 41 (Rated for Div. 2) F. k-substrings相关推荐
- Educational Codeforces Round 73 (Rated for Div. 2) F. Choose a Square 线段树 + 二维转一维
传送门 文章目录 题意: 思路: 题意: 给你nnn个点(xi,yi)(x_i,y_i)(xi,yi),每个点有个价值cic_ici,现在你可以框一个正方形,要求左下角和右上角的坐标(x,y)( ...
- Educational Codeforces Round 76 (Rated for Div. 2) F. Make Them Similar 折半搜索
传送门 文章目录 题意: 思路: 题意: 思路: 一个显然的思路就是2302^{30}230枚举所有的xxx,让后再检查,这个复杂度显然不能接受. 又发现对于每个位置它取多少不受其他位置限制,满足可拼 ...
- Educational Codeforces Round 41 (Rated for Div. 2)
这个D可以参考这个B的思路 A. Tetris time limit per test 1 second memory limit per test 256 megabytes input stand ...
- Educational Codeforces Round 41 (Rated for Div. 2) ABCDEF
最近打的比较少...就只有这么点题解了. A. Tetris time limit per test 1 second memory limit per test 256 megabytes inpu ...
- Educational Codeforces Round 81 (Rated for Div. 2) F.Good Contest \ 洛谷 划艇 组合 计数dp
cf传送门 P3643 [APIO2016]划艇 文章目录 题意: 思路: 题意: aia_iai在[li,ri][l_i,r_i][li,ri]等概率随机选一个数,求aaa数组不增的概率. 思 ...
- Educational Codeforces Round 101 (Rated for Div. 2) F. Power Sockets 哈希 + 乱搞
传送门 题意: 给一个二进制串aaa,让后定义两个串相似为有至少一个相同位置相等.现在让你找一个字典序最小的长度为kkk的串使其与aaa中每个长度为kkk的字串相似. 思路: 首先我们知道所有可能的串 ...
- Educational Codeforces Round 87 (Rated for Div. 2) F. Summoning Minions
题目链接 Polycarp plays a computer game. In this game, the players summon armies of magical minions, whi ...
- Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)
Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...
- Educational Codeforces Round 138 (Rated for Div. 2) D
Educational Codeforces Round 138 (Rated for Div. 2) D. Counting Arrays 题意 给定长度为nnn的数组aaa,若gcd(ai,i)= ...
最新文章
- redis-deskmanager 连不上 虚拟机 - centos redis
- 如何使用JPA和Hibernate映射JSON集合
- SQL Server数据库优化方案
- 云南计算机专修学校附中,昆明高中哪家强? 师附中和昆一中高考尖子生最多...
- 专科学计算机没有吗,我是专科生,学计算机信息管理专业的,我没有拿到..._考研_帮考网...
- PHP案例:连接数据库实现登录功能
- java 微信二次分享_微信二次分享
- [ML学习笔记] 回归分析(Regression Analysis)
- HDFS的Java操作
- SpringBoot系列(6)——使用AOP处理请求
- c语言sizeof输出单位,急,求大神!C语言中sizeof问题
- rar压缩包密码解密工具
- 饭前跑步还是饭后跑步 - 饭后多久跑步
- 环境会计信息披露问题研究
- 知识图谱初步学习(零)——本体是什么
- oracle c3p0 死锁,C3P0老是莫名其妙就线程死锁,但不影响程序
- can not access a member of class xxx with modifiers “private“
- python身份证识别
- 易飞ERP 算号服务 注册服务 服务器迁移 实施 二开 全版本
- 快速集成华为AGC云存储服务-Web