竞赛讨论区 > B msc和mcc
头像
秋招没工作
发布于 2018-11-15 23:40
+ 关注

B msc和mcc

B msc 和 mcc

题意:

对于一个字符串A,查询里面含有两个不重复子序列序列msc,mcc的子串个数

分析:

经过打表排除发现能够包含以下子序列的字符串都可以满足条件

char ch[10][100] = {"mccmsc","mcmcsc","mcmscc","mmccsc","mmcscc","mmsccc","mscmcc","msmccc"};

所以对于A的每一个位置i,找到最小的j,使得A[i,j] 包含上述子序列中的一个,这个位置的贡献是n-j+1,统计所有的贡献即可

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
char ar[maxn];
int  br[maxn];
int  nxt[maxn][4];
int  tmp[4];
map<char,int> ma;


char ch[10][100] = {"mccmsc","mcmcsc","mcmscc","mmccsc","mmcscc","mmsccc","mscmcc","msmccc"};
int Find(int a,int b){
   int j = 0;
   if(ar[a] == ch[b][0])
    j++;
   for(;j < 6; ++j){
    // cout<<"1"<<endl;
     int idx = ma[ch[b][j]];
     if(nxt[a][idx] != -1)
      a = nxt[a][idx];
     else
      return -1;
   }
   return a;
}
int main(){
  ma['m'] = 0;
  ma['s'] = 1;
  ma['c'] = 2;
  int n;
  cin>>n;
  cin>>(ar+1);
  for(int i = 1;i <= n; ++i)
    br[i] = ma[ar[i]];
  for(int i = 0;i < 4; ++i)
    tmp[i] = -1;
  for(int i = n;i >= 1; --i){
    for(int j = 0;j < 3; ++j)
      nxt[i][j] = tmp[j];
    tmp[br[i]] = i;
    // cout<<tmp[br[i]]<<endl;
    // cout<<i<<" "<<nxt[i][0]<<endl;
  }

  LL ans = 0;
  for(int i  = 1;i <= n; ++i){
    int Min = n+1;
    for(int j = 0;j < 8; ++j){
      int  t = Find(i,j);
      if(t != -1){
        Min = min(Min,t);
      }
    }
    if(Min == n+1)
      break;
    else
      ans += n-Min+1;
  }
  cout<<ans<<endl;



  return 0;
}

/*
mccmsc
mcmcsc
mcmscc
mcsmcc
mmccsc
mmcscc
mmsccc
mscmcc
msmccc
*/

全部评论

(0) 回帖
加载中...
话题 回帖

等你来战

查看全部

热门推荐