考虑求任意序列中$a$出现次数之和减去不合法序列中$a$出现次数之和,前者即为$(n-m+1)k^{n-m}$(一个序列重复次数恰好为$a$出现次数),对于后者,先忽略$a$的次数,即统计有多少个不合法序列

考虑dp,令$f[i][j]$表示前$i$个数,后$j$个数各不相同(且后$j+1$个数存在相同)的不合法序列数,转移对最后一个数分类讨论:

1.与第$i-j$个数不同,即长度增加1,则有$f[i][j]+=(k-(j-1))f[i-1][j-1]$

2.与第$i-j$个数相同,那么上一次长度任意,即$f[i][j]+=\sum_{t=j}^{k}f[i-1][t]$

暴力时间复杂度为$o(nk^{2})$,前缀和优化可以做到$o(nk)$,再考虑$a$的影响,对$a$分类讨论:

1.若$a$中包含一个$k$阶排列($a$合法),那么存在$a$必然合法,即不合法序列中$a$出现次数之和为0

2.若$a$中元素各不相同且$m<k$,定义$g[i][j]$表示所有$f[i][j]$序列中长为$m$且各不相同的子串数之和,转移类似,即在$j\ge m$时累计入$g[i][j]$中即可

同时,由于$m$个元素以及顺序已经确定,因此要除以$P(k,m)$(其中$P$为排列,即$P(n,m)=\frac{n!}{(n-m)!}$)

3.若$a$中包含相同的元素,令$x$为最大的$x$满足$[1,x]$中元素各不相同,$y$为最小的$y$使得$[y,m]$中元素各不相同,将整个序列分为$[1,x]$、$(x,y)$和$[y,m]$三部分

若$(x,y)$非空,那么即要求$(x,y)$不会影响其合法性,考虑如果存在一段长度为$k$的排列经过这个,那么必然不能完全在$[1,m]$内部(第一种情况),那么如果选择左边"出去",则不能选择到$x+1$,右边同理,即得证

具体来说,先枚举出现$a$的位置$i$,再枚举最后一段,即$\sum_{i=1}^{n}\frac{\sum_{j=x}^{k-1}f[i+x-1][j]}{P(k,x)}\cdot \frac{\sum_{j=m-y+1}^{k-1}f[n-(i-1)-(y-1)][j]}{P(k,m-y+1)}$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 25005
4 #define K 405
5 #define mod 1000000007
6 int n,m,k,ans,inv[K],a[N],vis[N],las[K],f[N][K],g[N][K];
7 int p_inv(int n,int m){
8 int ans=1;
9 for(int i=n-m+1;i<=n;i++)ans=1LL*ans*inv[i]%mod;
10 return ans;
11 }
12 int main(){
13 inv[0]=inv[1]=1;
14 for(int i=2;i<K-4;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
15 scanf("%d%d%d",&n,&k,&m);
16 for(int i=1;i<=m;i++)scanf("%d",&a[i]);
17 ans=n-m+1;
18 for(int i=1;i<=n-m;i++)ans=1LL*ans*k%mod;
19 int tot=0,flag=0,x,y;
20 for(int i=1;i<=m;i++){
21 if (++vis[a[i]]==1)tot++;
22 if ((i>k)&&(--vis[a[i-k]]==0))tot--;
23 if (tot==k){
24 printf("%d",ans);
25 return 0;
26 }
27 }
28 f[0][0]=1;
29 for(int i=1;i<=n;i++){
30 tot=0;
31 for(int j=k-1;j;j--){
32 tot=(tot+f[i-1][j])%mod;
33 f[i][j]=(1LL*(k-j+1)*f[i-1][j-1]+tot)%mod;
34 }
35 }
36 for(int i=1;i<=m;i++)las[a[i]]=i;
37 for(int i=1;i<=m;i++)
38 if (las[a[i]]!=i)flag=1;
39 if (!flag){
40 for(int i=1;i<=n;i++){
41 tot=0;
42 for(int j=k-1;j;j--){
43 tot=(tot+g[i-1][j])%mod;
44 g[i][j]=(1LL*(k-j+1)*g[i-1][j-1]+tot)%mod;
45 if (j>=m)g[i][j]=(g[i][j]+f[i][j])%mod;
46 }
47 }
48 tot=0;
49 for(int i=1;i<=k;i++)tot=(tot+g[n][i])%mod;
50 printf("%d",(ans+mod-1LL*tot*p_inv(k,m)%mod)%mod);
51 return 0;
52 }
53 memset(las,0,sizeof(las));
54 for(int i=1;i<=m;i++){
55 if (las[a[i]]){
56 x=i-1;
57 break;
58 }
59 las[a[i]]=1;
60 }
61 memset(las,0,sizeof(las));
62 for(int i=m;i;i--){
63 if (las[a[i]]){
64 y=i+1;
65 break;
66 }
67 las[a[i]]=1;
68 }
69 for(int i=1;(i+x-1<=n)&&(i-1<=n-(y-1));i++){
70 int s1=0,s2=0;
71 for(int j=x;j<k;j++)s1=(s1+f[i+x-1][j])%mod;
72 for(int j=m-y+1;j<k;j++)s2=(s2+f[n-(i-1)-(y-1)][j])%mod;
73 s1=1LL*s1*p_inv(k,x)%mod;
74 s2=1LL*s2*p_inv(k,m-y+1)%mod;
75 ans=(ans+mod-1LL*s1*s2%mod)%mod;
76 }
77 printf("%d",ans);
78 }

[atARC100F]Colorful Sequences的更多相关文章

  1. Atcoder 乱做

    最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...

  2. 【AtCoder】ARC100 题解

    C - Linear Approximation 找出\(A_i - i\)的中位数作为\(b\)即可 题解 #include <iostream> #include <cstrin ...

  3. ARC 100

    链接 https://arc100.contest.atcoder.jp/ C Linear Approximation 题解 把ai减去i后排序, 我们要的b就是排完序后的中位数 Code #inc ...

  4. AtCoder Regular Contest 100

    传送门 C - Linear Approximation 题意: 求 \[ \sum_{i=1}^nabs(A_i-(b+i)) \] \(A_i,b\)给出. 思路: 将括号拆开,变为\(A_i-i ...

  5. AtCoder练习

    1. 3721 Smuggling Marbles 大意: 给定$n+1$节点树, $0$为根节点, 初始在一些节点放一个石子, 然后按顺序进行如下操作. 若$0$节点有石子, 则移入盒子 所有石子移 ...

  6. [LeetCode] Repeated DNA Sequences 求重复的DNA序列

    All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...

  7. [Leetcode] Repeated DNA Sequences

    All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...

  8. 论文阅读(Weilin Huang——【AAAI2016】Reading Scene Text in Deep Convolutional Sequences)

    Weilin Huang--[AAAI2016]Reading Scene Text in Deep Convolutional Sequences 目录 作者和相关链接 方法概括 创新点和贡献 方法 ...

  9. leetcode 187. Repeated DNA Sequences 求重复的DNA串 ---------- java

    All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...

随机推荐

  1. Java秘诀!零基础怎样快速学习Java?

    对于零基础想学Java的朋友,其实一开始最应该做的就是定好学习目标和端正学习态度,切记不要三天打鱼两天晒网! 首先你是零基础,现在急需把Java学好,在保证学习质量的同时,用最短的时间学好Java应该 ...

  2. 2020.3.14--训练联盟周赛 Preliminaries for Benelux Algorithm Programming Contest 2019

    1.A题 题意:给定第一行的值表示m列的最大值,第m行的值表示n行的最大值,问是否会行列冲突 思路:挺简单的,不过我在一开始理解题意上用了些时间,按我的理解是输入两组数组,找出每组最大数,若相等则输出 ...

  3. 2021年1月-第02阶段-前端基础-HTML+CSS进阶-VS Code 软件

    软件安装 VSCode软件 能够安装 VS Code 能够熟练使用 VS Code 软件 能够安装 VS Code 最常用的插件 1. VS Code简介 1.1 VS Code 简介 Visual ...

  4. 关于 WinDoAdmin

    WinDoAdmin(有温度,更有深度) an amazing winform admin 框架描述 最新基于Winform实现的Web样式中后台解决方案,大型企业级开发框架. 如果你要使用Winfo ...

  5. python pip使用国内镜像安装第三方库:命令行或PyCharm

    python pip使用国内镜像安装第三方库:命令行或PyCharm 转载: https://blog.csdn.net/lly1122334/article/details/80646996

  6. 封装一个的toast弹出框(vue项目)

    逆风的方向,更适合飞翔 实现效果 实现步骤 先写出一个toast组件 // Toast.vue <template> <div id="toast" :class ...

  7. 机器学习:KNN

    KNN:K-nearst neighbors 简介: k-近邻算法采用测量不同特征值之间的距离来进行分类,简而言之为:人以类聚,物以群分 KNN既可以应用于分类中,也可用于回归中:在分类的预测是,一般 ...

  8. BUAA 软工 个人博客作业(一)

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人博客作业 我在这个课程的目标是 通过阅读<构建之法>大致了解软件工程 这个作业在哪 ...

  9. 使用Mybatis的TypeHandler加解密数据

    使用Mybatis的TypeHandler加解密数据 一.背景 二.解决方案 三.需求 四.实现思路 1.编写一个实体类,凡是此实体类的数据都表示需要加解密的 2.编写一个加解密的`TypeHandl ...

  10. Noip模拟63 2021.9.27(考场惊现无限之环)

    T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...