cf題面this
比勝過程中好像徹底沒有想法來着,打完比賽,羣裏分享的作法也並無看懂……一個月後的今天終於靠官方題解把題補了。spa
能夠用間接法,總的子串數量減去很差的子串數量就是好的子串數量。而很差的子串就4種——.net
其餘狀況都是好的子串。證實的話分類討論一下就好code
官方題解這麼說的——ip
Let's call a character \(t_i\) in string \(t_1t_2…t_k\) is bad if there is no such palindrome \(t_lt_{l+1}…t_r\) that \(l\leqslant i\leqslant r\). Any character in substring \(t_2t_3…t_{k−1}\) is good. It can be proven as follows. If \(t_i=t_i+1\) or \(t_i=t_i−1\) then \(t_i\) belong to a palindrome of length 2. If \(t_i\not = t_{i+1}\) and \(t_i≠t_{i−1}\) then \(t_i\) belong to a palindrome \(t_{i−1}…t_{i+1}\).rem
So only characters \(t1\) and \(tk\) can be bad. But at the same time character \(t1\) is bad if there is no character \(ti\) such that \(i>1\) and \(t_i=t_1\). It is true because substring \(t_1t_2…t_i\) is palindrome (index \(i\) is minimum index such that \(t_i=t_1\)).get
So, there are only 4 patterns of bad strings:iframe
All that remains is to count the number of substrings of this kind.string
寫的有點醜,原本能夠一個循環完事的。it
#include<cstdio> long long n; char s[300005]; int cnt[300005]={1},seg; long long ans; int main() { scanf("%lld",&n); scanf("%s",s); int pos=0; for(int i=1;i<n;i++) { if(s[i]==s[pos]) cnt[seg]++; else { seg++; cnt[seg]=1; pos=i; } } //for(int i=0;i<=seg;i++) printf("%d ",cnt[i]); ans=n*(n-1)>>1; for(int i=1;i<=seg;i++)// cnt[i] and cnt[i-1] { ans-=cnt[i-1]+cnt[i]-1; } printf("\n%lld\n",ans); return 0; }