欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

字符串(づ。◕‿‿◕。)づ进阶之章

发布时间:2024/3/12 编程问答 41 豆豆
生活随笔 收集整理的这篇文章主要介绍了 字符串(づ。◕‿‿◕。)づ进阶之章 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

字符串(づ。◕‿‿◕。)づ进阶之章

一、[国家集训队]最长双回文串

题目描述

顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同)。

输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1∣X∣,∣Y∣≥1)且X和Y都是回文串。

输入格式

一行由小写英文字母组成的字符串S。

输出格式

一行一个整数,表示最长双回文子串的长度。

输入输出样例

输入 #1

baacaabbacabb

输出 #1

12

说明/提示

【样例说明】

从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。

对于100%的数据,2≤∣S∣≤10^5

2018.12.10、2018.12.15 感谢 @Ycrpro 提供 hack 数据两组

先马拉车算法,然后记录左右边界这个时候记录的只有最大值的左右边界,然后再递推再更新醉的值,最后遍历一遍求出最大值即可

AC code

#include <bits/stdc++.h> //#pragma GCC optimize(3,"Ofast","inline") #define re register #define ll long long #define ull unsigned long longusing namespace std; //速读 inline int read() {int x=0,f=1;char ch=getchar();while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}return x*f; } const int N = 11000005; char a[N], s[N << 1]; int n, hw[N << 1], ans, l[N << 1], r[N << 1]; int main() {ios::sync_with_stdio(false);//接收数据scanf("%s", a + 1);n = strlen(a + 1);//间隔插入字符------预处理s[0] = '#';s[1] = '$';int cnt = 1;for(int i = 1; i <= n; i++){s[++cnt] = a[i];s[++cnt] = '$';}n = (n << 1) + 2;s[n] = '~';//预处理可以注意的地方:格式为#$a$b$c$~//manacherint mr = 0, mid = 0;for(int i = 1; i <= n; i++){//如果在之前的最右回文半径之内if(i < mr){//对比之前的对称点和最右回文半径,取相对靠左的那个hw[i] = min(hw[(mid << 1) - i], mr - i);}//再往右的话就只能暴力了else{hw[i] = 1;}//暴力扩展while(s[i + hw[i]] == s[i - hw[i]]){++hw[i];}//更新最大值if(hw[i] + i > mr){mr = hw[i] + i;mid = i;}//记录每个边界最大的回文距离r[i + hw[i] - 1] = max(r[i + hw[i] - 1], hw[i] - 1);l[i - hw[i] + 1] = max(l[i - hw[i] + 1], hw[i] - 1);}//递推,把前面的结果推到后面(因为前面更新的只是最大回文的情况,有些小回文会没有更新)for(int i = n; i >= 1; i -= 2){r[i] = max(r[i], r[i + 2] - 2);}for(int i = 1; i <= n; i += 2){l[i] = max(l[i], l[i - 2] - 2);}for(int i = 1; i <= n; i += 2){if(r[i] && l[i]){ans = max(ans, l[i] + r[i]);}}cout<<ans<<endl;return 0; }

二、[国家集训队]拉拉队排练

题目描述

艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了。拉拉队是篮球比赛的一个看点,好的拉拉队往往能帮助球队增加士气,赢得最终的比赛。所以作为拉拉队队长的楚雨荨同学知道,帮助篮球队训练好拉拉队有多么的重要。

拉拉队的选拔工作已经结束,在雨荨和校长的挑选下,n位集优秀的身材、舞技于一体的美女从众多报名的女生中脱颖而出。这些女生将随着篮球队的小伙子们一起,和对手抗衡,为艾利斯顿篮球队加油助威。

一个阳光明媚的早晨,雨荨带领拉拉队的队员们开始了排练。n个女生从左到右排成一行,每个人手中都举了一个写有26个小写字母中的某一个的牌子,在比赛的时候挥舞,为小伙子们呐喊、加油。

雨荨发现,如果连续的一段女生,有奇数个,并且他们手中的牌子所写的字母,从左到右和从右到左读起来一样,那么这一段女生就被称作和谐小群体。

现在雨荨想找出所有和谐小群体,并且按照女生的个数降序排序之后,前K个和谐小群体的女生个数的乘积是多少。由于答案可能很大,雨荨只要你告诉她,答案除以19930726的余数是多少就行了。

输入格式

输入为标准输入。

第一行为两个正整数n和K,代表的东西在题目描述中已经叙述。

接下来一行为n个字符,代表从左到右女生拿的牌子上写的字母。

输出格式

输出为标准输出。

输出一个整数,代表题目描述中所写的乘积除以19930726的余数,如果总的和谐小群体个数小于K,输出一个整数-1。

输入输出样例

输入 #1

5 3 ababa

输出 #1

45

说明/提示

样例说明

和谐小群体女生所拿牌子上写的字母从左到右按照女生个数降序排序后为ababa, aba, aba, bab, a, a, a, b, b,前三个长度的乘积为 。

数据范围与约定

测试点nK
11010
2-3100100
4-71,0001,000
8100,000= 1
9-11100,000100,000
12-14100,0001,000,000,000,000
15-17500,0001,000,000,000,000
181,000,000= 1
191,000,0001,000,000
201,000,0001,000,000,000,000

就是manacher模板,然后桶排序,再统计出前k即可

AC code

#include <bits/stdc++.h> //#pragma GCC optimize(3,"Ofast","inline") #define re register #define ll long long #define ull unsigned long long #define r read() using namespace std; //速读 inline int read() {int x=0,f=1;char ch=getchar();while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}return x*f; } const int N = 1000005; ll n, k,mr = 0, center, rl[N << 1], tong[N << 1], ans = 1;const int mod = 19930726; char s[N], str[N << 1]; inline ll ksm(ll x, ll y){ll res = 1;for(; y; y >>= 1, x = x * x % mod){if(y & 1){res = res * x % mod;}}return res; } int main() {ios::sync_with_stdio(false);int sum = 0;cin >> n>> k>> s + 1;for(re int i = 1; i <= n; i++){if(i <= mr){rl[i] = min(mr - i, rl[2 * center - i]);}else{rl[i] = 1;}while(rl[i] + i <= n && i - rl[i] >= 0 && s[i-rl[i]] == s[i+rl[i]]){rl[i]++;}if(rl[i] + i >= mr){mr = i + rl[i] - 1;center = i;}tong[rl[i] * 2 - 1]++;}if(n % 2 != 1){n--;}for(re int i = n; i >= 1; i -= 2){sum += tong[i];if(sum > k){ans = ans * ksm(i, k) % mod;cout<<ans<<endl;return 0;}else{ans = ans * ksm(i, sum) % mod;k -= sum;}}cout<<-1<<endl;return 0; }

总结

以上是生活随笔为你收集整理的字符串(づ。◕‿‿◕。)づ进阶之章的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。