最简单的解法应该是第i次时,当前的值为i*(i-1),假设下一步时值为(i+1) * i,然后应该加 (i+1) * (i+1) * i-i-1次。自己的想法是假设当前为m,那么要能开方且复合题意的话,要得到的值最小应该为mi=(i+1) * k,其中要满足(mi * mi -now)%i==0,k可以通过二分来找到,还要注意一点计算过程中会超过long long 的范围,所以要避免4个数连乘,先求与除数的公约数,之后再乘。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
ll ans[N];
ll get(ll x)
{
ll l=1;
ll r=x;
ll ret=x*(x+1);
while(l<=r)
{
ll m=(l+r)/2;
ll t=m*(x+1);
ll e=__gcd(t,x);
ll y=x/e;
ll f=__gcd(t,y);
ll z=y/f;
if(z==1)
{
r=m-1;
ret=t;
}
else
{
l=m+1;
}
}
return ret;
}
int main()
{
int n;
scanf("%d",&n);
ans[1]=2;
ll now=2;
for(ll i=2; i<=n; i++)
{
ll k=get(i);
ll e=__gcd(k,i);
ll j=i/e;
ans[i]=(k/e)*(k/j)-now/i;
now=k;
}
for(int i=1; i<=n; i++)
{
printf("%lld\n",ans[i]);
}
return 0;
}