正题
题目链接:https://jzoj.net/senior/#main/show/3798
题目大意
长度为nnn的字符串,求有多少个子串中ABCABCABC数量相等。
解题思路
方法好像很巧妙,用Si,A/B/CS_{i,A/B/C}Si,A/B/C表示到第iii个时A/B/CA/B/CA/B/C的数量。
然后Sr,A−Sl,A=Sr,B−Sl,B=Sr,C−Sl,CS_{r,A}-S_{l,A}=S_{r,B}-S_{l,B}=S_{r,C}-S_{l,C}Sr,A−Sl,A=Sr,B−Sl,B=Sr,C−Sl,C
Sr,A−Sl,A=Sr,B−Sl,B,Sr,A−Sl,A=Sr,C−Sl,CS_{r,A}-S_{l,A}=S_{r,B}-S_{l,B},S_{r,A}-S_{l,A}=S_{r,C}-S_{l,C}Sr,A−Sl,A=Sr,B−Sl,B,Sr,A−Sl,A=Sr,C−Sl,C
⇒\Rightarrow⇒
Sr,A−Sr,B=Sl,A−Sl,B,Sr,A−Sr,C=Sl,A−Sl,CS_{r,A}-S_{r,B}=S_{l,A}-S_{l,B},S_{r,A}-S_{r,C}=S_{l,A}-S_{l,C}Sr,A−Sr,B=Sl,A−Sl,B,Sr,A−Sr,C=Sl,A−Sl,C
定义cnti=(Sr,A−Sr,B)∗N+(Sr,A−Sr,C)cnt_i=(S_{r,A}-S_{r,B})*N+(S_{r,A}-S_{r,C})cnti=(Sr,A−Sr,B)∗N+(Sr,A−Sr,C)然后看有多少个相同的就好了。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+10;
long long n,sum[N][3],cnt[N],ans;
char s[N];
int main()
{scanf("%s",s+1);n=strlen(s+1);for(int i=1;i<=n;i++){sum[i][0]=sum[i-1][0];sum[i][1]=sum[i-1][1];sum[i][2]=sum[i-1][2];if(s[i]<='C')sum[i][s[i]-'A']++;cnt[i]=(sum[i][2]-sum[i][1])*N+sum[i][1]-sum[i][0];}sort(cnt,cnt+1+n);for(int i=0,j=0;j+1<=n;i=++j){while(j<n&&cnt[i]==cnt[j+1]) j++;ans+=1ll*(j-i+1)*(j-i)/2ll;}printf("%lld",ans);
}