• [数学]JZOJ 4673 LCS again


    Description

    现在有一个长度为n的串S,其中每一个字母都是前m个小写字母
    计算有多少个不同的长度为n的T(其中T也是由前m个小写字母组成),并且S与T的LCS为n-1
    LCS就是同时存在于S和T的最长子序列
     

    Input

    第一行包含两个整数n和m表示S的长度和前m个小写字母
    第二行是串S

    Output

    只要输出存在的T的数量
     

    Sample Input

    输入1:
    3 3
    aaa

    输入2:
    3 3
    aab

    输入3:
    1 2
    a

    输入4:
    10 9
    abacadefgh

    Sample Output

    输出1:
    6

    输出2:
    11

    输出3:
    1

    输出3:
    789

    样例解释
    第一个样例有6个可能的串T:aab,aac,aba,aca,baa,caa
    第二个样例有11个可能的串T
    Aaa,aac,aba,abb,abc,aca,acb,baa,bab,caa,cab
    第三个样例只有b
     

    Data Constraint

    对于20%,n<=100
    对于30%,n<=1000
    对于40%,n<=10000
    对于100%,n<=100000

    分析

    首先我们能看出来串T其实只能是删除一个字母以后再插入新字母的串S

    那么我们S中任意一个位删掉换成不是原字母的任意字母的方案数为n*(m-1)

    然后我们考虑一下,如果我们把连续的一段分块,那我们会发现,连续一段里面的所有字母拉出来以后再放进去是同一个效果的(重复方案)

    那么我们对于一个块只用考虑一个字母的贡献

    然后我们给一个串如:

    aaacb

    那我们把a移到c前面变换一下试试:aaacb,aabcb,aaccb

    移到b前面看看:aacab,aacbb,aaccb

    我们发现aaccb是重复的

    所以一个字母在前后只能用一次,每个块的贡献是n*(m-1)

    然而你会发现这样做还是有问题,如:

    ababab

    我们会发现相隔的两个字母(块)将会有重复计算的方案,所以还要再减去n*(m-1)(每对相隔的块减一次)

    #include <iostream> 
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    int n,m,cnt;
    char c[N];
    ll ans;
    
    int main() {
        scanf("%d%d",&n,&m);
        scanf("%s",c+1);
        ans=1ll*n*(m-1);
        for (int i=2;i<=n;i++) if (c[i]!=c[i-1]) ans+=1ll*n*(m-1);
        cnt=1;
        for (int i=2;i<=n;i++) {
            if (cnt==1&&c[i]!=c[i-1]) cnt++;
            else {
                if (cnt==1) continue;
                if (c[i]==c[i-2]) cnt++;
                else {
                    ans-=1ll*(cnt*(cnt-1)>>1ll);cnt=1;
                    if (c[i]!=c[i-1]) cnt++;
                }
            }
        }
        ans-=(cnt*(cnt-1)>>1ll);
        printf("%lld",ans);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    shell 冒泡算法 解决数组排序问题
    react(二)
    react(一)
    mybatis-plus:3
    lambda
    配置中心(nacos)-控制台使用
    nacos作为配置中心的简单项目配置
    nacos作为注册中心的简单项目配置
    Vue初步学习
    nacos单例模式简单搭建
  • 原文地址:https://www.cnblogs.com/mastervan/p/10645434.html
Copyright © 2020-2023  润新知