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. 学习blinker

    from blinker import signal do_sth = signal('do_sth') #创建信号 def process(f, a, b, **kwargs): f(a, b, * ...

  2. Oracle异常:Caused by: java.sql.SQLException: ORA-01536: 超出表空间 '登录名' 的空间限额 (JPA保存数据)

    原因: Oracle表空间为0,没有分配空间内存. 解决办法在代码框里: 1. 查看用户表空间的限额 select * from user_ts_quotas; max_bytes字段就是了 -1是代 ...

  3. Mac os下android studio模拟器无法联网解决方法

    步骤1: https://blog.csdn.net/qq_33945246/article/details/79908298 步骤2: 访达进入/Users/文件夹 步骤3: shift+cmman ...

  4. linux 基础 文件系统 用户权限

    描述Linux系统的启动过程? 1.开机自检 BIOS 2.MBR引导 3.GRUB菜单 4.加载内核 5.运行init进程 6.从/etc/inittab读取运行级别 7.根据/etc/rc.sys ...

  5. MD5盐值加密

    加密思路 思路解析:(数据解析过程基于16进制来处理的,加密后为16进制字符串) 加密阶段: 对一个字符串进行MD5加密,我们需要使用到MessageDigest(消息摘要对象),需要一个盐值(sal ...

  6. Linux 根据PID找到相应应用程序的运行目录

    1.找到运行程序的PID # ps aux | grep redis root pts/ S+ : : grep redis root ? Ssl Aug30 : redis-server *: # ...

  7. 用jstack自动化捕抓异常java代码脚本

    #!/bin/bashdate=` date +%y%m%d-%H%M`pid=`top -bn1 |grep java | awk '{print $1 "\t" $9}' |h ...

  8. php SQL 防注入的一些经验

    产生原因 一方面自己没这方面的意识,有些数据没有经过严格的验证,然后直接拼接 SQL 去查询.导致漏洞产生,比如: $id = $_GET['id']; $sql = "SELECT nam ...

  9. Java并发控制机制

    在一般性开发中,笔者经常看到很多同学在对待java并发开发模型中只会使用一些基础的方法.比如volatile,synchronized.像Lock和atomic这类高级并发包很多人并不经常使用.我想大 ...

  10. WPF触发器(Trigger) - DataTrigger

    官方文档中对DataTrigger的介绍 Represents a trigger that applies property values or performs actions when the ...