标签:计算 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 }
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)}$
标签:计算 spl 条件 std eve 答案 long prime key
原文地址:https://www.cnblogs.com/heoitys/p/11187990.html