題目描述
如果乙個字串可以被拆分為 aabb 的形式,其中 a和 b是任意非空字串,則我們稱該字串的這種拆分是優秀的。
例如,對於字串 aabaabaa,如果令 a=aab,b=a,我們就找到了這個字串拆分成 aabb的一種方式。
乙個字串可能沒有優秀的拆分,也可能存在不止一種優秀的拆分。比如我們令 a=a,b=baa,也可以用 aabb表示出上述字串;但是,字串 abaabaa 就沒有優秀的拆分。
現在給出乙個長度為 n的字串 s,我們需要求出,在它所有子串的所有拆分方式中,優秀拆分的總個數。這裡的子串是指字串中連續的一段。
以下事項需要注意:
1.出現在不同位置的相同子串,我們認為是不同的子串,它們的優秀拆分均會被記入答案。
2.在乙個拆分中,允許出現 a=b。例如 cccc 存在拆分 a=b=c。
3.字串本身也是它的乙個子串。
分析:
1.首先由題目想到列舉斷點,再統計以當前點為結尾的aa串的個數和以下一位為開頭的aa串的個數。
2.具體而言,可以列舉a的串長l,再令i=k*l,j=k*(l+1),分別統計出字尾i和字尾j的最長公共字首r以及字首i-1和j-1的最長公共字尾l,可以發現當(l+r)>=l 時,就會出現相應的一段區間滿足條件,再利用查分的思想統計答案即可。細節較多,需要仔細思考。
#include
#include
#include
#include
using
namespace
std;
const
int maxn=300010;
int n;
int log[maxn];
int pre[maxn],suf[maxn];
struct saffix_array
void build_sa(int m)
if(p>=n) break;
m=p;
}memcpy(rank,x,sizeof(rank));
int k=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=16;j++)
for(int i=1;i+(1
<1],height[i+(1
<<(j-1))][j-1]);}}
int lcp(int x,int y)}}
for(int i=1;i<=n;i++) pre[i]+=pre[i-1],suf[i]+=suf[i-1];
long
long ans=0;
for(int i=1;i<=n;i++) ans+=pre[i]*suf[i+1];
printf("%lld\n",ans);
}return
0;}
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...
NOI2016 優秀的拆分(字尾陣列)
如果乙個字串可以被拆分為aabbaabb的形式,其中 a和 b是任意非空字串,則我們稱該字串的這種拆分是優秀的。例如,對於字串aabaabaa,如果令 a aab,b a,我們就找到了這個字串拆分成 aabb的一種方式。乙個字串可能沒有優秀的拆分,也可能存在不止一種優秀的拆分。比如我們令 a a,b...