首先我们可以发现,长度为l的数组就是a数组不断循环构成。
令dp[i][j]表示操作到第j块,结尾是第i个数字时的结果。
\(dp[i][j]=\sum_{k=0}^{n-1}dp[k][j-1]\)但是这样复杂度过高。
于是,我们考虑前\(n\cdot k\)个数字。
在第j块中的第i个数字,其实转移,只有他前面的所有比他小的数字,我们考虑sort出前面n*k个数字的大小。从小到大遍历。
令f[i]表示第i个数字的贡献,\(sum[i]\)表示第i个块的贡献。
我们的\(f[i]=sum[\frac{i}{n}-1]\),表示第i个数字的贡献,来源于前面一个块,所以比他小的数字,即我们把第一个数字的\(\sum\)给变成sum,并且大小排序通过sort来实现。更新\(sum[i]+=f[i]\)即可。
紧接着考虑对ans的贡献,\(f[i]\)对ans的贡献=\((\frac{l-pos-1}{n}+1)\cdot f[i]\)
前面表示l到pos有多少个n在里面(因为是a数组不断滚动),然后加1(自己)。这样的话,就能表示长度为\(i\div n\),以\(a[i]\)结尾,的所以贡献值。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int mod = 1000000007;
const int N = 1e6 + 10;
ll n, l, k;
ll a[N];
struct node {
ll a, b;
bool operator<(const node temp)const
{
if (a == temp.a)
return b < temp.b;
else return a < temp.a;
}
};
ll sum[N]; ll dp[N];
int main()
{
n = read(), l = read(), k = read();
vector<node>vec(n*k);
up(i, 0, n)
{
a[i] = read();
vec[i] = node{ a[i],i };
}
up(i, n, n*k)
{
a[i] = a[i%n];
vec[i] = node{ a[i],i };
}
sort(vec.begin(), vec.end());
ll ans = 0;
up(i, 0, n*k)
{
ll temp = vec[i].a;
ll pos = vec[i].b;
if (pos < n)dp[pos] = 1;
else dp[pos] = sum[pos / n - 1];
sum[pos / n] += dp[pos];
sum[pos / n] %= mod;
ll dis = (l - pos - 1) / n + 1;
dis %= mod;
if (pos < l)
ans = (ans + (dp[pos] * dis % mod)) % mod;
}
cout << ans << endl;
return 0;
}