Problem

题目链接

Solution

吼题啊吼题!

首先如何求本质不同的子序列个数就是 \(f[val[i]]=1+\sum\limits_{j=1}^k f[j]\)

其中 \(f[i]\) 表示的是以 \(i\) 结尾的子序列个数

先把原数列的不同子序列个数求出来,然后观察一下这个转移,贪心的发现每次都是选一个最早出现的 \(i\) 填到序列末尾,然后更新这个值。

所以填的部分一定是 \(\frac mk\) 个 \(K\) 的排列,还有多出来了 \(m\%k\) 个元素暴力填进去。

每 \(K\) 个元素的转移是一样的,可以拿矩乘做。然后多余的部分求前缀积暴力求就行了。

Code

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cctype>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using std::min;
using std::max;
using std::swap;
using std::vector;
const int N=105;
const int M=1e6+5;
typedef double db;
typedef long long ll;
#define int long long
const int mod=1e9+7;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define mp(A,B) std::make_pair(A,B) int n,m,k,per[M];
int val[M];pii las[M]; struct Mat{
int a[N][N]; void clear(){
memset(a,0,sizeof a);
} void init(){
clear();
for(int i=1;i<=k+1;i++)
a[i][i]=1;
} void print(){
for(int i=1;i<=k+1;i++,puts(""))
for(int j=1;j<=k+1;j++)
printf("%lld ",a[i][j]);
} friend Mat operator*(Mat x,Mat y){
Mat z;z.clear();
for(int i=1;i<=k+1;i++){
for(int p=1;p<=k+1;p++){
for(int j=1;j<=k+1;j++)
z.a[i][j]=(z.a[i][j]+x.a[i][p]*y.a[p][j]%mod)%mod;
}
} return z;
}
}cs,f,qzh[N]; int getint(){
int X=0,w=0;char ch=0;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while( isdigit(ch))X=X*10+ch-48,ch=getchar();
if(w) return -X;return X;
} Mat ksm(Mat x,int y){
Mat ans;ans.init();
while(y){
if(y&1) ans=ans*x;
x=x*x;y>>=1;
} return ans;
} signed main(){
freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);
n=getint(),m=getint(),k=getint();
int sum=0;f.clear();f.a[1][k+1]=1;
for(int i=1;i<=k;i++) las[i]=mp(0,i);
for(int i=1;i<=n;i++){
val[i]=getint();
int p=f.a[1][val[i]];
f.a[1][val[i]]=(sum+1)%mod;
sum-=p;sum+=f.a[1][val[i]];sum%=mod;
las[val[i]]=mp(i,val[i]);
} std::sort(las+1,las+1+k);
qzh[0].init();
for(int i=1;i<=k;i++){
per[i]=las[i].second;
qzh[i].clear();
for(int j=1;j<=k+1;j++) qzh[i].a[j][j]=1;
for(int j=1;j<=k+1;j++) qzh[i].a[j][per[i]]=1;
qzh[i]=qzh[i-1]*qzh[i];
} cs=ksm(qzh[k],m/k);
cs=cs*qzh[m%k];
f=f*cs;int ans=0;
for(int i=1;i<=k;i++) (ans+=f.a[1][i])%=mod;
printf("%lld\n",ans);
return 0;
}

[JZOJ5836] Sequence的更多相关文章

  1. oracle SEQUENCE 创建, 修改,删除

    oracle创建序列化: CREATE SEQUENCE seq_itv_collection            INCREMENT BY 1  -- 每次加几个              STA ...

  2. Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等

    功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...

  3. DG gap sequence修复一例

    环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...

  4. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  5. [LeetCode] Sequence Reconstruction 序列重建

    Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. Th ...

  6. [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

  7. [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  8. [LeetCode] Longest Consecutive Sequence 求最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

  9. [LeetCode] Permutation Sequence 序列排序

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

随机推荐

  1. 20175316 盛茂淞 实验一 Java开发环境的熟悉

    20175316 盛茂淞 实验一 Java开发环境的熟悉 实验目的 使用JDK编译.运行简单的Java程序 实验要求 1.建立"自己学号exp1"的目录 2.在"自己学号 ...

  2. qhfl-4 注册-登录-认证

    认证 任何的项目都需要认证,当用户输入了用户名和密码,验证通过,代表用户登录成功 那HTTP请求是无状态的,下次这个用户再请求,是不可能识别这个用户是否登录的 就要有自己的方式来实现这个认证,用户登录 ...

  3. python open()函数的模式选择

    python open()函数打开文件的模式详解 使用python处理文件时,避免不了要用到open()函数.我们今天主要讨论mode参数的区分. fd = open('文件名(路径)’, mode= ...

  4. noip第18课资料

  5. 转 Master-Worker模式 并行程序设计模式--Master-Worker模式

    简介 Master-Worker模式是常用的并行设计模式.它的核心思想是,系统有两个进程协议工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负责处理子任务 ...

  6. Linux 线程编程1.0

    在编译多线程程序的时候,需要连接libpthread文件: gcc pthread.c  -o  pthread  -lpthread: 所有线程一律平等,没有父子关系,线程属于进程. 创建线程用 p ...

  7. Spring MVC 原理探秘 - 一个请求的旅行过程

    1.简介 在前面的文章中,我较为详细的分析了 Spring IOC 和 AOP 部分的源码,并写成了文章.为了让我的 Spring 源码分析系列文章更为丰富一些,所以从本篇文章开始,我将来向大家介绍一 ...

  8. [SRC初探]手持新手卡挖SRC逻辑漏洞心得分享

    文章来源i春秋 本文适合新手参阅,大牛笑笑就好了,嘿嘿末尾有彩蛋!!!!!!!!!!!!!!!!!本人参加了本次"i春秋部落守卫者联盟"活动,由于经验不足,首次挖SRC,排名不是那 ...

  9. Python加密与解密

    前言 据记载,公元前400年,古希腊人发明了置换密码.1881年世界上的第一个电话 保密专利出现.在第二次世界大战期间,德国军方启用“恩尼格玛”密码机, 密码学在战争中起着非常重要的作用. 随着信息化 ...

  10. 个人博客搭建( wordpress )

    最近同学买了一台虚机( centos7 系统 ).一个域名,让帮忙搭一个个人博客.本着简单快捷,个人博客采用 wordpress 来搭建.为了以后博客系统的迁移方便,使用 docker 来安装 wor ...