日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

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

编程问答

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

發布時間:2024/3/12 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符串(づ。◕‿‿◕。)づ进阶之章 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字符串(づ。????。)づ進階之章

一、[國家集訓隊]最長雙回文串

題目描述

順序和逆序讀起來完全一樣的串叫做回文串。比如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; }

總結

以上是生活随笔為你收集整理的字符串(づ。◕‿‿◕。)づ进阶之章的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。