如果乙個字串可以被拆分為 aabb的形式,其中 aa 和 bb 是任意非空字串,則我們稱該字串的這種拆分是優秀的。例如,對於字串 aabaabaa,如果令 a=aab,b=a,我們就找到了這個字串拆分成 aabb的一種方式。乙個字串可能沒有優秀的拆分,也可能存在不止一種優秀的拆分。比如我們令 a=a,b=baa,也可以用 aabb表示出上述字串;但是,字串 abaabaa 就沒有優秀的拆分。現在給出乙個長度為 n 的字串 s,我們需要求出,在它所有子串的所有拆分方式中,優秀拆分的總個數。這裡的子串是指字串中連續的一段。$sa$的力量= =以下事項需要注意:
出現在不同位置的相同子串,我們認為是不同的子串,它們的優秀拆分均會被記入答案。在乙個拆分中,允許出現 a=b。例如 cccc 存在拆分 a=b=c。字串本身也是它的乙個子串。
每個輸入檔案包含多組資料。輸入檔案的第一行只有乙個整數 t,表示資料的組數。保證 1≤t≤10。接下來 t 行,每行包含乙個僅由英文小寫字母構成的字串 s,意義如題所述。n≤30000
輸出 t 行,每行包含乙個整數,表示字串 s 所有子串的所有拆分中,總共有多少個是優秀的拆分。
4aabbbb
cccccc
aabaabaabaa
bbaabaababaaba35
47
顯然我們不用處理什麼$aabb$,只需要去處理所有$aa$形式,再去統計答案即可
設$pre[i]$表示以$i$這個字元開頭的$aa$型子串的數目
設$nxt[i]$表示以$i$這個字元結尾的$aa$型子串的數目
則答案$ans=\sum _^pre[i+1]\times nxt[i]$
所以問題就轉化成了求$aa$型的子串
我們可以列舉找的$aa$型子串長度的一半,去判斷$lcp$與$lcs$
列舉$i=k*len$,$j=i+len$
設$x=lcp(suffix(i),suffix(j))$,$y=lcs(pre(i-1),pre(j-1))$
若$x+y\geqslant len$,那麼我們就找到了$x+y-len+1$個長度為$2\times len$的$aa$串
差分一下就$gg$了
1 #include2 #include3 #include4view codeusing
namespace
std;
5#define mem(x) memset((x),0,sizeof((x)))
6struct
sa12 inline void
clear()
16 inline void
init()
20 inline void
suffix()
39for(i=1;i<=n;++i)rank[sa[i]]=i;
40for(i=1;i<=n;height[rank[i++]]=k)
41for(k?--k:0,j=sa[rank[i]-1];s[i+k]==s[j+k];++k);42}
43 inline void
st()
49 inline int lcp(int x,int
y)59 inline void
work()
63}a,b;
64 inline void
inv()
69 typedef long
long
l;70
l ans;
71 l cnt1[30005],cnt2[30005
];72 inline void
doit()85}
86for(int i=1;i<=a.n;++i)
87 cnt1[i]+=cnt1[i-1],cnt2[i]+=cnt2[i-1
];88
for(int i=1;i<=a.n;++i)
89 ans+=cnt1[i+1]*cnt2[i];
90 printf("
%lld\n
",ans);91}
92int
main()
103 }
NOI2016 優秀的拆分
看到題目,資料範圍有點怪異。對於95 的資料,對於100 的資料,意思是只有5分是正解。好吧,95pts的 很明顯,答案就是 而如何才能拿到100pts呢?我們可以先列舉a段的長度,很明顯每個長度為lcp,與往後求lcs,若 這樣就可以通過 include include include inclu...
NOI2016 優秀的拆分
題目實際上要求我們求從每個點出發的aa串的數量 考慮點i的答案,發現如果字首i與字首j j i 的最長公共字尾 i j,那麼i點出發向前就存在乙個長度為i j的aa串,題目即求對於每個字首,有多少個在他之前的字首滿足條件 考慮字尾自動機,由於每個字首都是字尾自動機parent樹上的一點,即兩個字首的...
NOI2016 優秀的拆分
點此看題 首先轉化問題,我們可以求出a i b i a i b i a i b i 即以i ii結束 開始的aaaa aa串的數量,這樣答案就可以表示為 a i b i 1 sum a i times b i 1 a i b i 1 求這兩個陣列,可以隔距離len lenle n設定乙個點,這樣乙個...