Codeforces Round #326 (Div. 2) D. Duff in Beach

D. Duff in Beach
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

While Duff was resting in the beach, she accidentally found a strange array b0, b1, ..., bl - 1 consisting of l positive 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.

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.

Input

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).

Output

Print the answer modulo 1 000 000 007 in one line.

Examples
Input
3 5 3
5 9 1
Output
10
Input
5 10 3
1 2 3 4 5
Output
25
Note

In the first sample case, . So all such sequences are: , , , , , , , , and .


【题意】给了一个长度为n的序列a,给一个长度为l<=10^18的序列b,其中b[i]=a[i%n]。求长度不超过k的b的不降子序列的个数,这个子序列的每个元素不能在一个周期里面。

【解题方法】解题方法来自http://blog.csdn.net/lwt36/article/details/50589276

【方法描述】由于每个周期最多只能选择一个,将a序列排序。考虑dp[i][j]:=长度为i,且以有序序列a第j个结尾的LIS的个数。转移的时候我们可以维护一个指针,这样转移就是均摊O(1)的了。统计答案时,由于是连续周期的,假如可选周期是T,当前长度为i,那么应该乘上(T−i+1)!

【补充】由于n*k<=10^6,那么动态开数组是必须的。

【时间复杂度】O(n*k)

【AC 代码】

//
//Created by just_sort 2016/9/16 10:12
//Copyright (c) 2016 just_sort.All Rights Reserved
//

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
const int mod = 1e9+7;
int n,K;LL l;
pair <int,int> a[maxn];

int main()
{
    //第一步输入数据排序
    scanf("%d%lld%d",&n,&l,&K);
    for(int i=0; i<n; i++){
        scanf("%d",&a[i].first);
        a[i].second=i;
    }
    std::sort(a,a+n);
    //第二步状态转移
    vector<vector<int> >dp(K,vector<int>(n));//动态数组,dp[i][j]代表长度为i,以有序序列a第j个结尾的lcs的个数
    for(int i=0; i<n; i++) dp[0][i] = 1;
    for(int i=1; i<K; i++){
        int sum = 0;
        for(int j=0,k=0; j<n; j++){
            while(k<n&&a[k].first<=a[j].first)
                sum = (sum+dp[i-1][k++])%mod;
            dp[i][j] = sum;
        }
    }
    //system("pause");
    //第3步,计算对答案的贡献
    LL ans = 0;
    LL T1=l/n,T2=l%n;
    for(int i=0; i<K; i++){
        for(int j=0; j<n; j++){
            LL cnt = T1 + (a[j].second<T2);
            if(cnt<=i) continue;
            ans+=((cnt-i)%mod*dp[i][j]%mod)%mod;
            ans %= mod;
        }
    }
    if(ans<0) ans+=mod;
    printf("%lld\n",ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值