• 11.24 考试


    T4
    求最长不下降子序列,因为最大值为150,并且数据产生方式有循环;
    所以可以找规律,在后面的时候,每经过一个循环节答案最大值+1;
    恶心的事循环节前面和后面的处理,很难调;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define LL long long
    using namespace std;
    const int N=1e5+7;
    LL n,tt,ans;
    int t0,A,B,C,D,ff=0;
    int vis[N],a[N],last[N];
    LL f[N];
    int main(){
    	freopen("lis.in","r",stdin);
    	freopen("lis.out","w",stdout);
    	scanf("%lld",&n);
    	scanf("%d%d%d%d%d",&t0,&A,&B,&C,&D);
    	a[1]=t0;
    	vis[a[1]]=1;
    	last[a[1]]=1;
    //	cout<<a[1]<<" ";
    	for(int i=2;i<=n;i++){
    		a[i]=1LL*(1LL*a[i-1]*a[i-1]*A+B*a[i-1]+C)%D;
    		tt=i;
    //		cout<<a[i]<<" ";
    		if(vis[a[i]]){
    			ff=1;
    			break;
    		}
    		vis[a[i]]=1;
    		last[a[i]]=i;
    //		if(a[i]==9) cout<<"------"<<i<<" ";
    	}
    //	cout<<"
    ";
    //	cout<<tt<<"
    ";
    //	cout<<a[tt]<<"
    ";
    	LL l=last[a[tt]];
    //	cout<<l<<"
    ";
    	if(ff==1) tt--;
    	LL uu=tt-l+1;
    //	cout<<uu<<"
    ";
    //	cout<<l<<" "<<"
    ";
    	LL ss=l-1+100*uu;
    	for(int i=1;i<=min(ss,n);i++){
    		if(i>tt) a[i]=1LL*(1LL*a[i-1]*a[i-1]*A+B*a[i-1]+C)%D;
    		LL maxn=0;
    		for(int j=1;j<i;j++){
    			if(a[j]<=a[i]){
    				maxn=max(maxn,f[j]);
    			}
    		}
    		f[i]=maxn+1;
    //		cout<<f[i]<<" ";
    	}
    	if(ff==0||ss>=n){
    		memset(f,0,sizeof(f));
    		for(int i=1;i<=n;i++){
    			if(i>tt) a[i]=1LL*(1LL*a[i-1]*a[i-1]*A+B*a[i-1]+C)%D;
    			LL maxn=0;
    			for(int j=1;j<i;j++){
    				if(a[j]<=a[i]){
    					maxn=max(maxn,f[j]);
    				}
    			}
    			f[i]=maxn+1;
    //			ans=max(ans,f[i]);
    		}
    		for(int i=1;i<=n;i++){
    			ans=max(ans,f[i]);
    		}
    		cout<<ans;
    		return 0;
    	}
    //	cout<<ss<<"
    ";
    	LL kk=n-ss;
    //	cout<<kk<<"
    ";
    	LL oo=kk/uu;
    	LL pp=0;
    //	cout<<"--"<<oo<<"
    ";
    	if(oo!=0){
    		oo--;
    		pp=uu;
    	}
    //	cout<<(uu*99+l)<<"
    ";
    	for(int i=(uu*99+l);i<=ss;i++){
    //		LL zz=(i-(l-1))/uu;
    //		if((i-(l-1))%uu==0) zz--;
    		f[i]+=oo;
    //		cout<<f[i]<<" ";
    	}
    //	cout<<"
    ";
    //	cout<<f[1]<<"
    ";
    	LL yy=kk%uu;
    //	cout<<yy<<"
    ";
    	pp+=yy;
    //	cout<<pp<<"
    ";
    	for(int i=ss+1;i<=ss+pp;i++){
    		if(i>ss) a[i]=1LL*(1LL*a[i-1]*a[i-1]*A+B*a[i-1]+C)%D;
    		LL maxn=0;
    		for(int j=1;j<i;j++){
    			if(a[j]<=a[i]){
    				maxn=max(maxn,f[j]);
    			}
    		}
    		f[i]=maxn+1;
    	}
    	for(int i=1;i<=ss+pp;i++){
    		ans=max(ans,f[i]);
    	}
    	cout<<ans;
    	fclose(stdin);
    	fclose(stdout);
    	return 0; 
    }
    /*
    309
    126 139 23 135 26
    
    707
    77 56 129 57 131
    
    10
    1 1 3 5 37
    
    1991
    128 128 73 113 75
    
    532889960237
    143 88 122 1 147
    
    1329
    30 104 50 130 136
    */
    

    T2
    给定一个数组,可以选两个数a,b;
    把a和b合并起来,就是a在前,b在后产生的一个新数;
    问有多少种选的方案,使得拼起来的数不是k的倍数;

    虑求有多少对(i; j)满足拼数结果为k的倍数。可以发现,对x; y拼数
    的本质是x*10⌊log10y⌋+1+y(这个式子不严谨,明白意思就行)。只要加号
    左边的与加号右边的对k取余的数能够加起来得到k或0即可。考虑
    枚举j,设j的位数为dig=⌊log10aj⌋+ 1,那么只要查询有多少个数满足乘10dig的结果对k取余为k

    #include<iostream>
    #include<cstdio>
    #include<map>
    #define LL long long
    using namespace std;
    const int N=2e5+7;
    int n,maxn;
    LL k,ans;
    LL a[N];
    map<int,int> S[11];
    int get(int x){
    	int res=0;
    	while(x!=0){
    		res++;
    		x/=10;
    	}
    	return res;
    }
    int main(){
    	freopen("piece.in","r",stdin);
    	freopen("piece.out","w",stdout);
    	scanf("%d%lld",&n,&k);
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&a[i]);
    		maxn=max(maxn,get(a[i]));
    	}
    	for(int i=1;i<=n;i++){
    		int tt=a[i];
    		for(int j=1;j<=maxn;j++){
    			tt=1LL*tt*10%k;
    			S[j][tt]++;
    		}
    	}
    	for(int i=1;i<=n;i++){
    		int tt=a[i];
    		int nod=get(a[i]);
    		for(int j=1;j<=nod;j++) tt=1LL*tt*10%k;
    		S[nod][tt]--;
    		if(a[i]%k){
    			ans+=S[nod][k-a[i]%k];
    		}else{
    			ans+=S[nod][0];
    		}
    		S[nod][tt]++;
    	}
    	cout<<1LL*n*(n-1)-ans;
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    /*
    4 11
    45 1 10 12
    */
    
    
  • 相关阅读:
    教育是什么?
    关于CTime::Format在Unicode下的输出问题及解决办法
    COleDateTime在Unicode下,Format函数会有问题。
    UNICODE字符集
    处理字符串String类和正则表达式
    关于datatable linq的转换
    js
    HDU 3874 Necklace
    HDU 1520 Anniversary party
    HDU 4314 Save the dwarfs
  • 原文地址:https://www.cnblogs.com/Aswert/p/14033851.html
Copyright © 2020-2023  润新知