码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2213 : [Poi2011]Difference

时间:2015-08-06 01:54:41      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

设f[i][j]为前i个字符中j出现的次数,则

ans=max((f[r][i]-f[l-1][i])-(f[r][j]-f[l-1][j]))=max((f[r][i]-f[r][j])-(f[l-1][i]-f[l-1][j])),其中f[r][j]!=f[l-1][j]。

考虑枚举r,当r从r-1变化到r时,f[r][i]-f[r][j]与f[r-1][i]-f[r-1][j]只有52个值会改变。

处理这52组(i,j),并求出min(f[l-1][i]-f[l-1][j])。

因为要满足f[r][j]!=f[l-1][j],所以要记录f[x][i]-f[x][j]的最小值和次小值及其对应的f[x][j],且要保证f[x][j]不相同。

若最小值对应的f[x][j]!=f[r][j],则取最小值,否则取次小值。

时间复杂度$O(26n)$。

 

#include<cstdio>
#define K 26
int n,i,j,k,c[K],b[K][K],f0[K][K],g0[K][K],f1[K][K],g1[K][K],ans;char a[1000010];
inline void max(int x){if(ans<x)ans=x;}
inline void up(int j,int k){
  if(g0[j][k]!=c[k])max(b[j][k]-f0[j][k]);else if(g1[j][k]!=c[k])max(b[j][k]-f1[j][k]);
  if(b[j][k]<f0[j][k]){
    if(c[k]!=g0[j][k])f1[j][k]=f0[j][k],g1[j][k]=g0[j][k];
    f0[j][k]=b[j][k],g0[j][k]=c[k];
  }else if(c[k]!=g0[j][k]&&b[j][k]<=f0[j][k])f1[j][k]=b[j][k],g1[j][k]=c[k];
}
int main(){
  scanf("%d",&n),gets(a),gets(a+1);
  for(i=1;i<=n;i++)for(c[j=a[i]-‘a‘]++,k=0;k<26;k++)if(k!=j)b[j][k]++,up(j,k),b[k][j]--,up(k,j);
  return printf("%d",ans),0;
}

  

BZOJ2213 : [Poi2011]Difference

标签:

原文地址:http://www.cnblogs.com/clrs97/p/4706260.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!