最簡單的解法應該是第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;
}