While Duff was resting in the beach, she accidentally found a strange array b0, b1, ..., bl - 1 consisting of lpositive integers. This array was strange because it was extremely long, but there was another (maybe shorter) array, a0, ..., an - 1 that b can be build from a with formula: bi = ai mod n where a mod b denoted the remainder of dividing a by b.
![](https://i-blog.csdnimg.cn/blog_migrate/dced985a5e3f91422aea6daa8633131a.png)
Duff is so curious, she wants to know the number of subsequences of b like bi1, bi2, ..., bix(0 ≤ i1 < i2 < ... < ix < l), such that:
- 1 ≤ x ≤ k
- For each 1 ≤ j ≤ x - 1,
- For each 1 ≤ j ≤ x - 1, bij ≤ bij + 1. i.e this subsequence is non-decreasing.
Since this number can be very large, she want to know it modulo 109 + 7.
Duff is not a programmer, and Malek is unavailable at the moment. So she asked for your help. Please tell her this number.
The first line of input contains three integers, n, l and k (1 ≤ n, k, n × k ≤ 106 and 1 ≤ l ≤ 1018).
The second line contains n space separated integers, a0, a1, ..., an - 1 (1 ≤ ai ≤ 109 for each 0 ≤ i ≤ n - 1).
Print the answer modulo 1 000 000 007 in one line.
解题思路:
首先比较容易发现的特性就是既然每一段都只能取一个数字,所以在完整的一段内数字的次序其实不重要,所以我们可以将数字排序,这会方便我们之后的一些操作。
定义 dp[i][j] = 以编号为 j 的数字结尾的长度为 i 的序列有多少个
所以转移就相当于 dp[i][j] = ∑ dp[i-1][ 0-w ] w为小于等于编号j的数字的最大的编号
这样编号0-w的数字都一定小于第j个数字 这样我们就能通过之前的到的长度为 i - 1 的序列得到长度为 i 的序列。
到这里这道题完成了第一步,下一步需要考虑答案的组成。
先不考虑 n不能整除l 的时候
考虑 l 非常大的时候,长度为 i 的序列其实可能出现很多次 次数等于 l / n - i + 1 所以需要将这个倍数和对应位置的dp值乘在一起。
考虑 n不能整除l 的时候
单独考虑剩余的那些数,其实只需要计算以他们为结尾,长度为 1,2,3,。。。的序列的个数就可以了~
AC代码:
/*
* @Author: wchhlbt
* @Last Modified time: 2017-10-02
*/
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define pb push_back
#define AA first
#define BB second
#define ONES(x) __builtin_popcount(x)
#define _ << " " <<
using namespace std;
typedef pair<int, int> P;
typedef long long ll ;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
const double eps =1e-8;
const int mod = 1000000007;
const double PI = acos(-1.0);
inline int read(){ int num; scanf("%d",&num); return num;}
const int maxn = 1000007;
int a[maxn];
int b[maxn];
int pos[maxn];//记录数字所对应的最大编号在哪里
vector<ll> dp[maxn];//dp[i][j] 表示 以编号j的数字为结尾的长度为i的序列的个数
map<int,int> id;
ll ans;
int main()
{
ll n,k,l;
cin>>n>>l>>k;
for(int i = 0; i<n; i++){
a[i] = read();
b[i] = a[i];
}
sort(b,b+n);
for(int i = 0; i<n; i++) id[b[i]] = i; //记录一下重排之后数字的编号
ll m = min(l/n,k);
int res = l%n;
for(int i = 0; i<n; i++){
dp[1].pb(1);
pos[i] = id[b[i]];
}
for(int i = 2; i<=m+1; i++){ //计算完整部分的dp值,这里最好算到m+1层
ll s = 0; int x = 0;
for(int j = 0; j<n; j++){
while(x<=pos[j]) s = (s + dp[i-1][x++])%mod;
dp[i].pb(s);
}
}
for(int i = 1; i<=m; i++)
for(int j = 0; j<n; j++)
ans = (ans + dp[i][j] * ((l/n-i+1)%mod) )%mod; //注意乘法和取模的优先级
for(int i = 0; i<res; i++){ //处理剩余的部分
int o = id[a[i]];
for(int j = 1; j<=min(k,l/n+1); j++){ //注意这里层数的上界
ans = (ans + dp[j][o])%mod;
}
}
cout << ans << endl;
return 0;
}