期望得分:100+100+20=220
实际得分:100+100+20=220
(好久没有期望==实际了 ,~\(≧▽≦)/~)
对于 a。。。。。。。。a
如果 第1个a 后面出现的第1个b~z 是右端点,且在第2个a之前,那么有贡献
如果 第2个a 前面出现的第1个b~z 是左端点,且在第1个a之后,那么有贡献
最后的贡献/2
#include<cstdio> #include<cstring> #define N 100001 using namespace std; char s[N]; int LAST[26],last[N],pre[N][26],suf[N][26]; bool w[N],c[26]; int main() { freopen("cross.in","r",stdin); freopen("cross.out","w",stdout); scanf("%s",s+1); int len=strlen(s+1),ans=0,ch; for(int i=1;i<=len;i++) for(int j=0;j<26;j++) if(s[i]-'a'==j) pre[i][j]=i; else pre[i][j]=pre[i-1][j]; for(int i=0;i<26;i++) suf[len][i]=len+1; suf[len][s[len]-'a']=len; for(int i=len-1;i;i--) for(int j=0;j<26;j++) if(s[i]-'a'==j) suf[i][j]=i; else suf[i][j]=suf[i+1][j]; for(int i=1;i<=len;i++) { ch=s[i]-'a'; c[ch]^=1; w[i]=!c[ch]; if(c[ch]) LAST[ch]=i; else last[i]=LAST[ch]; } for(int i=1;i<=len;i++) if(w[i]) { for(int j=0;j<26;j++) if(j!=s[i]-'a') { if(suf[last[i]][j]<i && w[suf[last[i]][j]]) ans++; if(pre[i][j]>last[i] && !w[pre[i][j]]) ans++; } } printf("%d",ans>>1); }