可以知道,当T较大时,对于LIS,肯定会有很长的一部分是重复的,而这重复的部分,只能是一个block中出现次数最多的数字组成一序列。所以,对于T》1000时,可以直接求出LIS,剩下T-=1000直接求出现次数最多的数字的个数即可。其实可以不用到1000,只需到n即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector> using namespace std; const int MAX=105;
int p[MAX*MAX*10];
int a[MAX],n,t,m;
int dp[MAX*MAX*10]; int bin(int l,int r,int key){
while(l<=r){
int mid=(l+r)>>1;
if(dp[mid]>key&&dp[mid-1]<=key) return mid;
if(dp[mid]>key) r=mid-1;
else l=mid+1;
}
return 1;
} int LIS(int len){
int res=1; dp[res]=p[1];
for(int i=2;i<=len;i++){
if(p[i]>=dp[res]){
dp[++res]=p[i];
}
else{
int pos=bin(1,res,p[i]);
dp[pos]=p[i];
}
}
///cout<<res<<endl;
return res;
} void slove(int l){
int ans=LIS(l);
/// cout<<ans<<endl;
sort(a+1,a+1+n);
int counts=1,maxlen=1;
for(int i=2;i<=n;i++){
if(a[i]==a[i-1]) counts++;
else{
if(counts>maxlen) maxlen=counts;
counts=1;
}
}
if(counts>maxlen) maxlen=counts;
printf("%d\n",ans+(t-m)*maxlen);
} int main(){
while(scanf("%d%d",&n,&t)!=EOF){
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
m=min(1000,t);
dp[0]=-1e9+7;
for(int i=0;i<m;i++){
for(int j=1;j<=n;j++){
p[i*n+j]=a[j];
dp[i*n+j]=1e9+7;
}
}
slove(m*n);
}
return 0;
}