L1-006 连续因子
思路:
从中分解出最长的连续因子,可以先分解
的因子,然后双指针去找。
1.如果所取因子与已经选了的因子递增,且它们的乘积小于等于n,那么选上这个点
2.如果不递增,则不要以前取了的因子
3.如果当前的因子和已经选了的因子的乘积不是n的因子了,那么将前面的因子抛弃(给当前的因子一个机会)直到乘积是n的因子
如果写的时候思路不清晰,执行上面的步骤容易出错,如果每次枚举递增因子序列的起点,然后分解n,从而找到递增因子序列,这样不容易出错,出错了也容易发现并解决。
我的思路重点放在了因子上,写的时候概念变淡了,忽视了递增子序列必须是n的因子(写的时候会忘的,比如,求出了
,明显是错的,没想到会出现这个情况)。同时对一处更清楚了,(
,它的因子有
),很明显的,如果把
合成
,
,就是最长递增因子序列了,这就是步骤3的必要。
Code:
#include<bits/stdc++.h> using namespace std; int a[50005],tot; int main() { long long n,i,mx,sum,pos,j,tmp; scanf("%lld",&n); for(long long i=2; i*(i-1)<=n; ++i) { if(n%i==0) a[++tot]=i; } i=1,j=i+1,mx=1,sum=a[1],pos=a[1],tmp=1; if(tot==0) mx=1,pos=n; while(j<=tot) { if(sum*a[j]>n) break; if(a[j]-a[j-1]==1&&n%(sum*a[j])==0) { sum*=a[j]; tmp+=1; if(tmp>mx) { pos=a[i]; mx=tmp; } } else { if(a[j]-a[j-1]!=1) { sum=1; i=j; tmp=0; } while(i<j&&n%(sum*a[j])!=0) { sum/=a[i]; i+=1; tmp-=1; } sum*=a[j]; tmp+=1; } j+=1; } printf("%lld\n%lld",mx,pos); for(j=pos+1; j<pos+mx; ++j) printf("*%lld",j); puts(""); return 0; }