Project Euler 221
题目
Alexandrian Integers
We shall call a positive integer an “Alexandrian integer”, if there
exist integers such
that:
For example, is an
Alexandrian integer ().
In fact, is the Alexandrian integer, the
first Alexandrian integers being:
and .
Find the
Alexandrian integer.
解决方案
可以发现, 中必定有其中一个数是正数,其余两个数是负数,假设 是正数, 是负数。
因此问题等价于如下形式:
寻找 ,其中 ,使得
消去 ,不难得到
两边都加一个 ,那么可以写成
那么,先枚举 ,再枚举 的因子 ,那么可以得到 ,最终得到题目中要求的一个数:
令 ,那么使用 216 题的分解方式对 进行分解:如果 ,那么 ,其中 。再根据分解产生其所有因子。
本题 的上限难以确定,如果查询的值为 ,那么就假设为 。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include <bits/stdc++.h> typedef long long ll; using namespace std; const int Q = 150000; const int M = Q*2/3+100; const ll MX = 1e18; ll f[M+4]; unordered_map<ll,int>fact[M+4]; int main(){ for(int i=1;i<=M;i++) f[i]=1ll*i*i+1; for(int i=1;i<=M;i++){ ll p=f[i]; if(p==1) continue; for(ll j=i;j<=M;j+=p) while(f[j]%p==0) f[j]/=p,++fact[j][p]; for(ll j=p-i;j<=M;j+=p) while(f[j]%p==0) f[j]/=p,++fact[j][p]; } vector<ll>a; for(ll p=1; p <= M; p++){ ll n= p*p+1; vector<ll>divs{1}; for(auto &[pr,e]:fact[p]){ int l=0,r=divs.size(); for(int _ = 0;_ < e;_++){ for(int j=l;j<r;j++) if(divs[j]*divs[j]*pr*pr<=n) divs.push_back(divs[j]*pr); l=r;r=divs.size(); } } for(ll d:divs){ if(p*(p+d)>MX/(p+(p*p+1)/d)) continue; a.push_back(p*(p+d)*(p+(p*p+1)/d)); } } sort(a.begin(),a.end()); ll ans=a[Q-1]; printf("%lld\n",ans); }
|