传送门
发现这题选或不选对状态的优劣程度不会产生影响,如果已经确定了两个数a和b,那么最优的首项和公比也都是唯一确定的,
与对于后面的数x,加进去也好不加进去也好,首项和公比依旧是原来的
于是我们用尺取算法,用两个指针来扫一遍,
如果只有一个数且下一个数能被整除,就加进去,然后确定首项和公比
如果只有一个数且下一个数不能整除,两个指针直接指向下一个数
如果有多个数且下一个数满足公式,就加进来
如果有多个数且下一个数不满足公式,两个指针直接指向下一个数
这样对于最优解,一定是可以找到的
顺便说下最优的公比和首项的确定:
已知两个数x y,求满足它们的最优的首项 公比
设x=a*q^k1 y=a*q^k2 且x>y
那么x/y得到q^(k1-k2),
由于最优的公比一定尽可能小,所以要使指数尽可能大,就把q质因数分解,指数取gcd提出
这样就得到了公比,拿这个公比不断地除以一开始的x,就得到了首项
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<map> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 #define INF 0x7f7f7f7f 11 #define pii pair<int,int> 12 #define ll long long 13 #define MAXN 100005 14 using namespace std; 15 16 ll read(){ 17 ll x=0,f=1;char ch=getchar(); 18 while(ch<‘0‘||ch>‘9‘){if(‘-‘==ch)f=-1;ch=getchar();} 19 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 20 return x*f; 21 } 22 int n; 23 set<ll> s; 24 ll a[MAXN]; 25 int gcd(int x,int y){ 26 return (y==0?x:gcd(y,x%y)); 27 } 28 ll Pow(ll x,ll y){ 29 ll ret=1; 30 while(y){ 31 if(y&1){ 32 ret*=x; 33 } 34 x*=x; 35 y>>=1; 36 } 37 return ret; 38 } 39 int gt(ll x,ll y,ll &b,ll &q){ 40 ll t=x/y; 41 if(1==t){ 42 b=x,q=1; 43 return 1; 44 } 45 vector<pii> vs; 46 for(int i=2;i<=1000;i++){ 47 if(t%i==0){ 48 int cnt=0; 49 while(t%i==0){ 50 cnt++; 51 t/=i; 52 } 53 vs.push_back(make_pair(i,cnt)); 54 } 55 } 56 if(t>1000){ 57 return -1; 58 } 59 int g=vs[0].second; 60 for(int i=1;i<vs.size();i++){ 61 g=gcd(g,vs[i].second); 62 } 63 q=1; 64 for(int i=0;i<vs.size();i++){ 65 q*=Pow((ll)vs[i].first,(ll)vs[i].second/g); 66 } 67 b=y; 68 while(b%q==0){ 69 b/=q; 70 } 71 return 1; 72 } 73 int check(ll x,ll b,ll q){ 74 if(x%b){ 75 return 0; 76 } 77 if(q==1){ 78 return (x==b); 79 } 80 if(s.count(x)){ 81 return 0; 82 } 83 x/=b; 84 ll t=q; 85 int L=0,R=log(1.0*x)/log(1.0*q)+3; 86 while(R-L>1){ 87 int mid=(L+R)/2; 88 ll t=Pow(q,(L+R)/2); 89 if(t>=x){ 90 R=mid; 91 } 92 else{ 93 L=mid; 94 } 95 } 96 if(Pow(q,L)==x||Pow(q,R)==x){ 97 return 1; 98 } 99 return 0; 100 } 101 int main() 102 { 103 // freopen("seq2.in","r",stdin); 104 // freopen("seq.out","w",stdout); 105 n=read(); 106 for(int i=1;i<=n;i++){ 107 a[i]=read(); 108 } 109 int L=1,R=1; 110 int ans=1; 111 ll b=0,q=0; 112 s.insert(a[1]); 113 for(int i=2;i<=n;i++){ 114 ll t1=a[R],t2=a[i]; 115 if(t1<t2){ 116 swap(t1,t2); 117 } 118 if(t1%t2!=0){ 119 s.clear(); 120 s.insert(a[i]); 121 L=i,R=i; 122 continue; 123 } 124 if(L==R){ 125 R++; 126 s.insert(a[R]); 127 if(-1==gt(t1,t2,b,q)){ 128 L++; 129 s.clear(); 130 s.insert(a[L]); 131 } 132 } 133 else if(check(a[i],b,q)){ 134 R++; 135 if(q!=1) 136 s.insert(a[R]); 137 } 138 else{ 139 s.clear(); 140 s.insert(a[i]); 141 L=i,R=i; 142 } 143 ans=max(ans,R-L+1); 144 } 145 printf("%d\n",ans); 146 return 0; 147 }
时间: 2024-10-08 02:47:27