zoukankan      html  css  js  c++  java
  • [Wannafly挑战赛28][B msc和mcc][预处理+枚举]

    链接:https://ac.nowcoder.com/acm/contest/217/B
    来源:牛客网

    msc和mcc

    题目描述

    msc和mcc是一对好朋友,有一天他们得到了一个长度为n的字符串s.

    这个字符串s十分妙,其中只有’m’,’s’和’c’三种字符。

    定义s[i,j]表示s中从第i个到第j个字符按顺序拼接起来得到的字符串。

    定义一个字符串t的子序列为从t中选出一些位置并且将这些位置上面的字符按顺序拼接起来得到的字符串。

    两个子序列重合当且仅当存在一个位置x使得两个子序列同时选择了位置x。

    由于msc和mcc是一对很好很好的好朋友,所以她们希望选择两个数字x和y满足1≤x≤y≤n使得s[x,y]中同时存在两个**不重合的子序列**使得其中一个是’msc’且另外一个是’mcc’

    现在给出n和字符串s,问她们可以选出多少对不同的(x,y)。

    输入描述:

    第一行一个正整数n,表示字符串s的长度。

    第二行一个长度为n的字符串s,其中s只包含字符’m’,’s’和,’c’。(n<100000)

    输出描述:

    一行一个正整数,表示答案。
    题目大意:给一个字符串,求有多少个区间内部存在msc 和 mcc 两个子序列(并且二者不存在公共元素)
    题目分析:由于n是1e5级别的,并且是要对区间进行计数,所以只能在O(N)的时间复杂度下得到最终结果,可以想到枚举区间左端点O(N),然后就需要O(1)得到右端点的个数,右端点的个数也就是n-符合条件的最小右端点,所以这个时候只能预处理,而可以知道满足条件的长度为6的子序列只有8种,所以可以预处理出每种情况下的每一个元素后一个元素的位置,然后就能O(1)得到最小右端点了.
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<map>
     5 #include<cstdio>
     6 #include<algorithm>
     7 using namespace std;
     8 typedef long long ll;
     9 int n;
    10 char ch[8][7]={
    11     "012022",
    12     "010222",
    13     "001222",
    14     "002212",
    15     "022012",
    16     "020122",
    17     "020212",
    18     "002122"
    19 };
    20 int nx[100005][4],kt[100005];
    21 char s[100005];
    22 int main(){
    23     cin>>n;
    24     scanf("%s",s+1);
    25     for(int i=1;i<=n;i++){
    26         if(s[i]=='m')kt[i]=0;
    27         else if(s[i]=='s')kt[i]=1;
    28         else kt[i]=2;
    29     }
    30     for(int i=0;i<3;i++){
    31         int pos=n+1;
    32         for(int j=n;j>=0;j--){
    33             nx[j][i]=pos;
    34             if(kt[j]==i)pos=j;
    35         }
    36     }
    37     ll ans=0;
    38     for(int i=1;i<=n;i++){
    39         int ed=n+1;
    40         for(int j=0;j<8;j++){
    41             int pos=i-1;
    42             for(int k=0;k<6&&pos<=n;k++){pos=nx[pos][ch[j][k]-'0'];}
    43             ed=min(ed,pos);
    44         }
    45         ans+=n-ed+1;
    46     }
    47     cout << ans << endl;
    48     return 0;
    49 }
    View Code
    
    
    
     
  • 相关阅读:
    Appium 服务关键字(转)
    android自动化之appium的环境搭建
    关于性能测试几个名词概念的说明
    关于.net服务启动注册到zookeeper,但是注册节点20分钟自动消失解决办法
    关于tomcat启动报“this web application instance has been stopped already”的处理
    loadrunner在win10破解提示:Cannot save the license information because acceses to the registry is denied的解决办法
    Teamcity部署.net服务“无法连接到远程服务器”解决方式
    数据库主从不同步问题随笔
    eclipse 常用快捷键
    在linux中安装jdk以及tomcat并shell脚本关闭启动的进程
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/9943590.html
Copyright © 2011-2022 走看看