zoukankan      html  css  js  c++  java
  • HZOI20190714 T1序列

    什么沙雕题啊……考察的是啥啊,分类咋搞啊……愁死我了……

    先把作者的正解放出来:

    序列
    因为选出的一段是一个等比序列的子序列,我们分为两种情况:
    1. q=1,相当于找一个最长每个数都相等的子串,这个扫一遍就行了。
    2. q!=1,那么这个序列最长只有 logn,那么我们可以枚举开头,不妨设开始的两个数为 a[i]和 a[i+1],
    其中比较大的一个为 x,另一个 y。
    (1) 首先要满足 x%y=0
    (2) 让 z=x/y,然后把 z 质因数分解,z=p1^q1*p2^q2*p3^q3......,设 g=gcd(q1,q2,q3...),那么当前序
    列的最小公比就是 p1^(q1/g)*p2^(q2/h)*......
    (3) 我们找到最小公比后,每当往后加一个数,判断它与前边的数的比是否是最小公比的整次幂,
    不是的话就说明不能再加了。
    (4) 还有一个要求就是这个序列里不能有重复的数,这个东西用 set 判断就行了。
    复杂度 nlog2 n
    Ps:因为这道题的数据实在是不好造,所以最后公比最大不会很大,可能有很多其他算法也能跑过去。

    然而各路大佬各种nb的暴力卡数据都A掉了这题,(只有我这个蒟弱暴力都能爆0……)

    首先求出q=1时的答案ans,

    枚举q1~1000,如果ans个q乘起来超过了数列的最大值,break;

    然后就是一个&n^2&的暴力,用map处理重复的数,复杂度好高……

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<set>
    #include<map>
    #define int LL
    #define LL long long
    #define ma(x) memset(x,0,sizeof(x))
    #define max(a,b) ((a)>(b)?(a):(b))
    using namespace std;
    int n;
    LL A[200010];
    LL l=1,r=100000,mid,q;
    LL ans=1,maxn;
    map<int,int> mp;
    inline LL read()
    {
    	LL s=0;char a=getchar();
    	while(a<'0'||a>'9')a=getchar();
    	while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
    	return s;
    }
    LL gcd(int a,int b){return !b?a:gcd(b,a%b);}
    signed main()
    {
    //	freopen("in.txt","r",stdin);
    //	freopen("0.out","w",stdout);
    
    	n=read();
    	for(int i=1;i<=n;i++)A[i]=read(),maxn=max(maxn,A[i]);
    	int L=0,R=0;r=n;
    	for(int i=1;i<=n;i++)
    	{
    		if(A[i]==A[i-1]&&!L)L=i-1;
    		if(A[i]!=A[i-1]&&L)ans=max(ans,i-L),L=i;
    	}
    	if(A[n]==A[n-1])ans=max(ans,n-L+1);
    	bool pd=0;
    	for(int q=2;q<=100;q++)
    	{
    		int tem=0;
    		for(int i=1;i<=ans;i++)	
    		{
    			tem*=q;if(q>maxn){pd=1;break;}
    		}
    		if(pd)break;
    		for(int i=1;i<=n;i++)
    		{
    			mp.clear();
    			int tem=A[i];
    			mp[tem]=1;
    			if(tem%q!=0&&tem>q){continue;}
    			while(tem%q==0)tem/=q;
    //			while(tem>=q)tem/=q;
    			for(int j=i+1;j<=n;j++)
    			{
    				int te=A[j];
    				if(mp.find(te)!=mp.end()){ans=max(ans,j-i);break;}
    				if(te%q!=0&&te!=tem){ans=max(ans,j-i);break;}
    				while(te%q==0)te/=q;
    				if(te!=tem){ans=max(ans,j-i);break;}
    			}
    		}
    	}
    	printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    即时通讯之环信视频语音实时通话与单聊和群聊实现
    检测.net framework 版本
    Abp(.NetCore)开发与发布过程3-部署Ubuntu站点
    Abp(.NetCore)开发与发布过程2
    Abp(.NetCore)开发与发布过程
    Redis实战与 Session缓存
    Redis 安装与初体验
    [转]gluPerspective函数
    [转]gluLookAt 函数详解
    [转]unity3D游戏开发之GUI
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11186759.html
Copyright © 2011-2022 走看看