【模拟7.14】序列 (质因数分解,数论)

这次考崩了,本来以为可以T1骗点分,看了题面后想了二分,心想40分稳了,然后就干后面的题,最后爆了十分

long long没加,二分时相乘数太大,本以为能骗分。。。。。

这题首先就不讲了,

正解其实不难首先要质因数分解,

 因为选出的一段是一个等比序列的子序列,我们分为两种情况:
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 判断就行了。

然后用辗转相除法处理出kx_1,kx_2的比是否为base的整数幂

一开始把辗转相除忘了。。。

质因数分解板子:(将每个数的因子及幂放起来,注意处理质数)

 1 void work_zhi(ll x)
 2 {
 3     ll kx=x;
 4     for(ll kkk=2;kkk<=min1(sqrt(kx),1000);++kkk)
 5     {
 6        if((kx%kkk)==0)
 7        {
 8           th.ps(kkk);
 9           ll sum=0;
10           while((kx%kkk)==0)
11           {
12                 sum++;
13                 kx/=kkk;
14           }
15           c.ps(sum);
16        }
17    }
18    if(kx>1){
19       th.ps(kx);c.ps(1);
20    }
21    return ;
22 }
View Code

AC代码

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<vector>
  7 #include<cmath>
  8 #include<bits/stdc++.h>
  9 #include<stack>
 10 #include<queue>
 11 #include<set>
 12 #define MAXN 1000001
 13 #define ps push_back 
 14 #define pt printf("--------
");
 15 #define ll long long 
 16 using namespace std;
 17 vector<ll>th,c;
 18 ll n,a[MAXN];
 19 ll min1(ll x,ll y){
 20    if(x<y)return x;else return y;
 21 }
 22 
 23 void work_zhi(ll x)
 24 {
 25     ll kx=x;
 26     for(ll kkk=2;kkk<=min1(sqrt(kx),1000);++kkk)
 27     {
 28        if((kx%kkk)==0)
 29        {
 30           th.ps(kkk);
 31           ll sum=0;
 32           while((kx%kkk)==0)
 33           {
 34                 sum++;
 35                 kx/=kkk;
 36           }
 37           c.ps(sum);
 38        }
 39    }
 40    if(kx>1){
 41       th.ps(kx);c.ps(1);
 42    }
 43    return ;
 44 }
 45 bool judge(ll x,ll y,ll p){
 46   // printf("jude%lld %lld
",x,y);
 47    /*if(x<y)swap(x,y);
 48    ll zheng=1;
 49    ll yuan=x;
 50    while(x>=y&&(ll)y!=1){
 51        x=x/y;
 52        zheng*=y;
 53    }
 54    x=1;zheng*=y;
 55    printf("jj x=%lld y%lld
",x,y);
 56    if(zheng*x==yuan)return 1;
 57    else return 0;*/
 58   // printf("y=%lld x=%lld
",y,x);
 59    while(y<x){y*=p;}
 60    if(x==y)return 1;
 61    else return 0;
 62 }
 63 set<ll>kxx;
 64 bool judge1(ll x,ll y){ 
 65     
 66     if(x<y)swap(x,y);
 67     ll q=x/y;
 68     if(y*q==x)return 1;
 69     else return 0;
 70 }
 71 ll gcd(ll a,ll b){return (b==0)?a:(gcd(b,a%b));}
 72 int main()
 73 {
 74    //freopen("kx.in","r",stdin);
 75   // freopen("kx.out","w",stdout);
 76    scanf("%lld",&n);
 77    for(ll i=1;i<=n;++i){
 78       scanf("%lld",&a[i]);
 79    }
 80    ll maxn=1,sum=1;
 81    for(ll i=2;i<=n;++i){
 82      
 83       if(a[i]==a[i-1]){
 84          sum++;maxn=max(maxn,sum);
 85       }
 86       else{
 87          sum=1;
 88       }
 89    }
 90   // printf("maxn=%lld
",maxn);
 91    ll ans=0;
 92    for(ll i=2;i<=n;++i)
 93    {
 94       kxx.clear();
 95       ans=1;
 96       ll x_1=i,x_2=i-1;
 97       ll kx_1=a[i],kx_2=a[i-1];
 98       if(kx_1<kx_2){
 99          swap(kx_1,kx_2);swap(x_1,x_2);
100       }
101       ll zz=kx_1/kx_2;
102    //   printf("kx_1=%lld kx_2=%lld
",kx_1,kx_2);
103       if(!judge1(kx_1,kx_2))continue;
104       if(zz==1)continue;
105       work_zhi(zz);ll gcdd=c[0];
106       for(ll i=1;i<c.size();++i){
107           ll kkk=c[i];
108           gcdd=gcd(gcdd,kkk);
109       }
110    //   printf("gcdd=%lld kx_1=%lld kx_2=%lld
",gcdd,kx_1,kx_2);
111       kxx.insert(a[i]);kxx.insert(a[i-1]);
112       ans=2;maxn=max(maxn,ans);
113       ll base=1;
114       for(ll k=0;k<c.size();++k){
115           for(ll j=1;j<=c[k]/gcdd;++j){
116               base*=th[k];
117           }
118       }
119  //    printf("base=%lld
",base);
120       c.clear();th.clear();
121       for(ll j=i+1;j<=n;++j)
122       {
123          if(kxx.count(a[j])!=0){break;}
124          else kxx.insert(a[j]);
125  //        printf("----------%lld
",*kxx.find(a[j]));
126          ll to2=a[j];
127  //        printf("a[%lld]=%lld
",j,a[j]);
128          if(kx_2>to2){
129             swap(kx_2,to2);
130          }
131   //     printf("to/kx_2%lld base%lld
",to2/kx_2,base);
132          if(judge(to2,kx_2,base)==1){
133            ans++;maxn=max(ans,maxn);//printf("ans=%lld maxn=%lld
",ans,maxn);
134          } 
135          else {
136            break;
137          }
138       }
139       kxx.clear();
140    }
141    printf("%lld
",maxn);
142 }
View Code

************************************************************

set中常用的方法

begin()        ,返回set容器的第一个元素

end()      ,返回set容器的最后一个元素

clear()          ,删除set容器中的所有的元素

empty()    ,判断set容器是否为空

max_size()   ,返回set容器可能包含的元素最大个数

size()      ,返回当前set容器中的元素个数

rbegin     ,返回的值和end()相同

rend()     ,返回的值和rbegin()相同

原文地址:https://www.cnblogs.com/Wwb123/p/11191202.html