zoukankan      html  css  js  c++  java
  • [atARC100F]Colorful Sequences

    考虑求任意序列中$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$且各不相同的子串数之和,转移类似,即在$jge 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 } 
    View Code
  • 相关阅读:
    面向对象的继承关系体现在数据结构上时,如何表示
    codeforces 584C Marina and Vasya
    codeforces 602A Two Bases
    LA 4329 PingPong
    codeforces 584B Kolya and Tanya
    codeforces 584A Olesya and Rodion
    codeforces 583B Robot's Task
    codeforces 583A Asphalting Roads
    codeforces 581C Developing Skills
    codeforces 581A Vasya the Hipster
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13939746.html
Copyright © 2011-2022 走看看