1 条题解
-
0
自动搬运
来自洛谷,原作者为

Prean
不断倒下,不断站起来,不停地与自己作斗争搬运于
2025-08-24 22:33:37,当前版本为作者最后更新于2021-08-23 18:18:38,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意:给定 ,求方程 的所有解,且解必须满足 。
以下内容搬运自官方题解:
转化一下:
根据 ,有:
$$\gcd(\frac {bn} {b+n},b,n)=\gcd(\frac {bn} {b+n},\gcd(b,n))=1 $$接下来设 ,那么一定有 。
于是:
$$\gcd(\frac {xy} {x+y} \times \gcd(b,n),\gcd(b,n))=1 $$而 是整数,所以有 。
于是 $ x+y=\gcd(b,n),b+n=\gcd(b,n) \times (x+y) = \gcd(b,n)^2 $。
相当于求方程 。(这里的 在上面是 )
下面为了方便,设 。
然后对于 ,枚举可行的 ,最后检查一下是否合法就行。
检查是否合法的瓶颈在于,计算 $ \gcd(x,c)=\gcd(d(d-k),c)=\gcd(d(d-k),dk)=d \times \gcd(d-k,k) $。
这里的 和 一定有一个数不大于 ,所以根据 ,可以直接预处理一个 的表。
再往下推,发现实际上是判断 ,也就是判断 和 是否互质,所以打表可以使用一个 bool 类型的数组来降低常数。
到这里,复杂度已经变成 的了。在加强版中,这个做法只跑了 1s,并且卡掉了 的暴力,还在原版跑到了300ms。
#include<cstdio> #include<vector> typedef unsigned uint; typedef unsigned long long ull; const uint M=2e6; uint T,mx,n[100005],ans1[M+5];bool _check[1420][1420]; ull ans[M+5],ans2[M+5]; inline ull min(const ull&a,const ull&b){ return a>b?b:a; } signed main(){ register uint i,j,x; scanf("%u",&T);_check[0][1]=true; for(i=1;i<=1415;++i)_check[1][i]=true; for(i=2;i<=1415;++i){ for(x=0,j=i;j<=1415;++j){ _check[i][j]=_check[x][i]; if(++x==i)x=0; } } for(i=1;i<=T;++i)scanf("%u",n+i),mx=n[i]>mx?n[i]:mx; for(i=1;i<=mx;++i)ans2[i]=0x7f7f7f7f7f7f7f7f; for(i=1;i<=mx;++i){ for(j=1,x=i;j<=i&&x<=mx;++j,x+=i){ if(_check[i%j][j])ans2[x]=min(ans2[x],1ull*i*(i-j)),++ans1[x]; } } for(ans1[i=1]=0;i<=mx;++i)ans1[i]+=ans1[i-1]; for(i=1;i<=T;++i)printf(n[i]==1?"0\n":"%u %llu\n",ans1[n[i]],ans2[n[i]]); }
- 1
信息
- ID
- 7148
- 时间
- 2000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者