D. Duff in Beach

题意  数字串a[0---n-1], 通过不断的重复组成了 b[0,---l-1]l<10^18,  

让你计算出 长度小于等于k的最长非递减子序列,满足,取得第 i 个取得是 L1 第i+1个取得是L2  ------ L1/n +1 = L2, 通过这个我们先对原数组进行排序,排完后使用vector去计算dp[i][j]

及时 第i个数放在第j位的方案总数, 然后我们依次枚举放1 个 2 个3个。。。k, 贡献分别是  l/n,l/n-1....1,这样再枚举那最后的余下的那一些。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <string.h>
using namespace std;
const int maxn=1000006;
typedef long long LL;
const LL mod=1000000007;
int A[maxn],B[maxn],C[maxn],D[maxn],E[maxn];
vector<LL>G[maxn];
void init(int n,int k)
{
    for(int i=0; i<=n; i++)
        {
             G[i].clear();
             for(int j=0; j<=k; j++)G[i].push_back(0);
        }
}
int main()
{
    int n,k;LL l;
    while(scanf("%d%I64d%d",&n,&l,&k)==3)
    {
        init(n,k);
        for(int i=0;i<n; i++)
        {
            scanf("%d",&A[i]);
            B[i]=A[i];
        }
        sort(B,B+n);
        int ge=1;
        C[0]=1;
        for(int i=1; i<n;i++)
        {
            if(B[i]==B[ge-1])C[ge-1]++;
            else{
                B[ge++]=B[i]; C[ge-1]=1;
            }
        }
        LL num=l/n;
        LL ans=l%mod;
        LL uu=min(k*1LL,num+1);
        int lest=l%n,numoflest=1;
        sort(A,A+lest);
        if(lest>0){
            E[0]=1;

            for(int i=1; i<lest; i++)
            {
                if(A[i]==A[numoflest-1])E[numoflest-1]++;
                else{
                    A[numoflest++]=A[i]; E[numoflest-1]=1;
                }
            }
        }
        for(int i=0; i<ge; i++)G[i][1]=C[i];
        for(int i=2; i<=k; i++)
            {
                 long long d=0,S=0;
                 int loc=0;
                 for(int j=0; j<ge; j++)
                 {
                     d+=G[j][i-1];
                     d=d%mod;
                     G[j][i]=(d*C[j])%mod;
                     S=(S+G[j][i])%mod;
                     while(loc<lest&&A[loc]<B[j])loc++;
                     if(loc<lest && A[loc] == B[j])
                     {
                         if(i<=uu)
                            ans=(ans+(d*E[loc])%mod )%mod;
                     }
                 }
                 if( num - i + 1 > 0 )
                 {
                    long long  gg=( S * ( ( num - i + 1 )%mod ) )%mod;
                    ans=(ans+gg)%mod;
                 }
            }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

posted @ 2015-10-24 21:18  来自大山深处的菜鸟  阅读(251)  评论(0编辑  收藏  举报