码迷,mamicode.com
首页 > 其他好文 > 详细

序列(20190714考试)

时间:2019-07-15 12:08:01      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:计算   spl   条件   std   eve   答案   long   prime   key   

内部资料,题面不传

暴力二分答案应该可以过,反正考试时就靠这个得了20

正解: 当公比=1时,扫一遍统计

   当公比!=1时,序列最长logN,枚举开头两个a[i],a[i+1],计算最小公比q,

for循环往后找,如果a[j]与a[j-1]的比值是q的整次幂,把a[j]加进去,否则跳出,开头++,接着跑,当然,碰到有重复出现的也要跳出

枚举开头复杂度N,枚举后面的序列logN,判断是否可行logN ,总复杂度(N $log^2$N)

  计算最小公比用分解质因数(p1^q1*p2^q2……),计算质因数个数的gcd,  q=p1^(q1/gcd)*p2^(q2/gcd)……

  判断是否是整次幂 while(x%q==0) x/=q; 最后x==1 x即为q的整次幂

技术图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<set>
 4 using namespace std;
 5 set<long long>s;
 6 int n,prime[1100],v[1100];
 7 long long q,ans,len,a[110000];
 8 long long max(long long a,long long b){return a>b?a:b;}
 9 long long min(long long a,long long b){return a<b?a:b;}
10 long long gcd(long long a,long long b){    return b?gcd(b,a%b):a;}
11 void primes(){
12     for(int i=2;i<=1000;i++){
13         if(v[i]==0){
14             v[i]=i;
15             prime[++prime[0]]=i;
16         }
17         for(int j=1;j<=prime[0];j++){
18             if(prime[j]>v[i]||prime[j]>1000/i) break;
19                 v[i*prime[j]]=prime[j];
20         }
21     }
22 }
23 long long fenjie(long long q){
24     long long ans=1,zhi[100],num[100];
25     zhi[0]=0;
26     for(int i=1;i<=prime[0];i++){
27         if(q%prime[i]==0){
28             zhi[++zhi[0]]=prime[i];
29             num[zhi[0]]=0;
30             while(q%prime[i]==0) q/=prime[i],num[zhi[0]]++;
31         }
32         if(q==1) break;
33     }
34     if(q!=1) return 0;
35     long long d=num[1];
36     for(int i=2;i<=zhi[0];i++){
37         d=gcd(d,num[i]);
38         if(d==1) break;
39     }
40     for(int i=1;i<=zhi[0];i++){
41         num[i]/=d;
42         while(num[i]) ans=(long long)ans*zhi[i],num[i]--;
43         if(ans>1000) return 0;
44     }
45     return ans;
46 }
47 bool judge(long long x,long long y){
48     if((x==1&&y!=1)||(x!=1&&y==1)) return false;
49     while(x%y==0) x/=y;
50     if(x==1) return true;
51     return false;
52 }
53 int main(){
54     scanf("%d",&n);
55     primes();
56     for(int i=1;i<=n;i++)    scanf("%lld",&a[i]);
57     long long ans=0,len=1;
58     for(int i=2;i<=n;i++){
59         if(a[i]==a[i-1]) len++;
60         else ans=max(ans,len),len=1;
61     }
62     ans=max(ans,len);
63     for(int i=1;i<n;i++){
64         long long w=max(a[i],a[i+1]),t=min(a[i],a[i+1]),r=w/t;
65         if(w%t!=0) continue;
66         q=fenjie(r);
67         if(q==0) continue;
68         s.insert(a[i]),s.insert(a[i+1]);
69         for(int j=i+2;j<=n;j++){
70             w=max(a[j],a[j-1]),t=min(a[j],a[j-1]),r=w/t;
71             if(w%t!=0||s.find(a[j])!=s.end()||!judge(r,q)) break;
72             s.insert(a[j]);
73         }
74         ans=max(ans,s.size());
75         s.clear();
76     }
77     printf("%lld\n",ans);
78 }
View Code

  secret大大还有另一种算法,计算当前序列的最大公比Q1与a[j]和a[j-1]的比值Q2 是否有最大的q使Q1是q的整次幂,Q2也是q的整次幂,是则插入,否则跳出

  枚举开头用单队维护,期望复杂度(N logN)(牛X~)

  她是用反复Q1/Q2(大除小,辗转相除)最后Q1==Q2,即为原Q1Q2最大的满足上述条件的q

  Lockey简单证明一下:

    设存在一个比较小的q满足条件 Q1=q^k1,Q2=q^k2 (Q1>Q2)

    Q1/Q2=$q^{k1-k2}$ 辗转相除,相当于k1%k2,最后最大的q=$q^{gcd(k1,k2)}$

  

序列(20190714考试)

标签:计算   spl   条件   std   eve   答案   long   prime   key   

原文地址:https://www.cnblogs.com/heoitys/p/11187990.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!