如果乙個字串可以被拆分為aabbaabb的形式,其中 a和 b是任意非空字串,則我們稱該字串的這種拆分是優秀的。
例如,對於字串aabaabaa,如果令 a=aab,b=a,我們就找到了這個字串拆分成 aabb的一種方式。
乙個字串可能沒有優秀的拆分,也可能存在不止一種優秀的拆分。比如我們令 a=a,b=baa,也可以用 aabb表示出上述字串;但是,字串 abaabaa就沒有優秀的拆分。
現在給出乙個長度為 n的字串s,我們需要求出,在它所有子串的所有拆分方式中,優秀拆分的總個數。這裡的子串是指字串中連續的一段。
以下事項需要注意:
出現在不同位置的相同子串,我們認為是不同的子串,它們的優秀拆分均會被記入答案。
在乙個拆分中,允許出現a=b。例如 cccc存在拆分a=b=c。
字串本身也是它的乙個子串。
每個輸入檔案包含多組資料。
輸入的第一行只有乙個整數t,表示資料的組數。保證 1≤t≤10。
接下來 t行,每行包含乙個僅由英文小寫字母構成的字串s,意義如題所述。
輸出 t行,每行包含乙個整數,表示字串s所有子串的所有拆分中,總共有多少個是優秀的拆分。
輸入 #1
4
aabbbb輸出 #1cccccc
aabaabaabaa
bbaabaababaaba
3
5給定乙個字串,從裡面查詢一共有多少個字串滿足aabb形式,輸出個數47
【演算法分析】
考慮這個拼接的情況,aabb
所以我們只需要找所有的aa/bb,然後左乘右獲得最終答案
然後問題就轉化成了如何求aa和bb
利用字尾陣列我們能夠在nlogn的時間複雜度內求取出lcp
同時我們把字串翻轉,然後就能夠求到lcs
而這兩個字串如果重合,就說明能夠出現aa的這種形式的重複
定義:f [ i ] 為以 i 開頭的符合條件的aa型字串
g [ i ] 為以 i 結尾的符合條件的aa型字串
然後我們只需要把他們 相乘累加即可
注意:
最後乙個不能夠重疊,所以最後乙個位置( n )不符合要求
【**】
#include#includeview code#include
#include
#include
using
namespace
std;
const
int maxn = 30000+ 5
;int
lg[maxn], f[maxn], g[maxn];
struct
suff_string
, y[maxn] = , c[maxn] = ;
intsa[maxn], rak[maxn], height[maxn];
int st[17
][maxn];
void build_sa(char *s)
for (int i = 1; i <= n; i++)
rak[sa[i]] =i;
return
; }
void get_height(char *s)
}void
build_st()
int query(int l, int
r)
}a,b;
char
s[maxn];
void
solve()}}
//printf("**\n");
for (int i = 1; i <= n; i++)
f[i] += f[i - 1], g[i] += g[i - 1
];
long
long ans = 0
;
for (int i = 1; i 1
]; printf(
"%lld\n
", ans);
}int
main()
return0;
}
紀念我水過的第二道黑題
NOI2016優秀的拆分 字尾陣列
題目描述 如果乙個字串可以被拆分為 aabb 的形式,其中 a和 b是任意非空字串,則我們稱該字串的這種拆分是優秀的。例如,對於字串 aabaabaa,如果令 a aab,b a,我們就找到了這個字串拆分成 aabb的一種方式。乙個字串可能沒有優秀的拆分,也可能存在不止一種優秀的拆分。比如我們令 a...
NOI2016 優秀的拆分 字尾陣列
題目鏈結 洛谷點我 uoj點我 題目描述 如果乙個字串可以被拆分為 aabb 的形式,其中 a和 b是任意非空字串,則我們稱該字串的這種拆分是優秀的。例如,對於字串 aabaabaa,如果令 a aab,b a,我們就找到了這個字串拆分成 aabb的一種方式。乙個字串可能沒有優秀的拆分,也可能存在不...
字尾陣列 NOI2016 優秀的拆分
如果乙個字串可以被拆分為 aa bb的形式,其中 a 和 b 是任意非空字串,則我們稱該字串的這種拆分是優秀的。例如,對於字串 aabaabaa,如果令 a aab,b a,我們就找到了這個字串拆分成 aa bb的一種方式。乙個字串可能沒有優秀的拆分,也可能存在不止一種優秀的拆分。比如我們令 a a...