zoukankan      html  css  js  c++  java
  • CF #323 DIV2 D题

    可以知道,当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
    ",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;
    }
    

      

  • 相关阅读:
    网络编程
    Ant path 匹配原则
    Android Html.fromhtml
    android AsyncTask
    Android 系统联系人相关URI
    Android 学习心得体会
    中国天气网api(json格式)
    android:textAppearance
    Android COLLATE LOCALIZED ASC
    Android 快递接口
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4856550.html
Copyright © 2011-2022 走看看