Codeforces Round #828 (Div. 3) E1 E2

心已赠人 2024-03-30 13:07 193阅读 0赞

Problem - E1 - Codeforces

Problem - E2 - Codeforces

题意:

给定a,b,c,d,其中 a<x<=c,b<y<=d,问是否存在这样的x,y使得x*y能被a*b整除

思路:

E1:

我们去从a+1到c枚举 x ,x*y能被a*b整除可以转化为 y能被a*b/gcd(a*b,x)整除(这个可以用唯一分解质因数去感性理解,y 必须包含 a*b的所有质因子除去x的所有质因子,所有问题就转化成:去求区间[b+1,d]里的a*b/gcd(a,b)的倍数,那么直接取最靠近右边界的倍数就好了

设s=a*b/gcd(a*b,s)

答案就是(d/s)*s,这里是下取整

注意边界情况,边界如果是s的倍数就直接特判输出

如果区间内不存在s的倍数,就判无解

否则就输出最靠近右边界的倍数

Code:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. int a,b,c,d;
  5. void solve(){
  6. cin>>a>>b>>c>>d;
  7. for(int x=a+1;x<=c;x++){
  8. int s=(a*b)/__gcd(a*b,x);
  9. if((b+1)%s==0){
  10. cout<<x<<" "<<b+1<<'\n';
  11. return;
  12. }
  13. if((b+1)/s==d/s){
  14. continue;
  15. }
  16. cout<<x<<" "<<(d/s)*s<<'\n';
  17. return;
  18. }
  19. cout<<-1<<" "<<-1<<'\n';
  20. }
  21. signed main(){
  22. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  23. int __=1;cin>>__;
  24. while(__--)solve();return 0;
  25. }

E2:

因为x*y能被a*b整除,因此x*y一定含有a*b的因子,所以我们去dfs枚举a*b的所有因子,放到数组里,然后去枚举其中一个因子x,构造另一个因子a*b/x,去构造超过a的第一个倍数和超过b的第一个倍数就好了

Code:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. const int mxn=4e4+5000;
  5. vector<pair<int,int> > v;
  6. map<int,int> mp;
  7. int a,b,c,d,t,len=0,cnt=0;
  8. int vis[mxn],prime[mxn],divd[mxn];
  9. void initd(int n){
  10. for(int i=2;i<=n;i++){
  11. if(!vis[i]) prime[++len]=i;
  12. for(int j=1;prime[j]<=n/i;j++){
  13. vis[i*prime[j]]=1;
  14. if(i%prime[j]==0) break;
  15. }
  16. }
  17. }
  18. void dfs(int u,int p){
  19. if(p>c) return;
  20. if(u==v.size()){
  21. if((a*b)/p<=d) divd[++cnt]=p;
  22. return;
  23. }
  24. for(int i=0;i<=v[u].second;i++){
  25. dfs(u+1,p);
  26. p*=v[u].first;
  27. }
  28. }
  29. void init(){
  30. len=0,cnt=0;
  31. mp.clear();v.clear();
  32. memset(divd,0,sizeof(divd));
  33. }
  34. void solve(){
  35. init();
  36. cin>>a>>b>>c>>d;
  37. t=a;
  38. for(int i=1;prime[i]<=t/prime[i];i++){
  39. int p=prime[i];
  40. if(t%p==0){
  41. while(t%p==0) t/=p,mp[p]++;
  42. }
  43. }
  44. if(t>1) mp[t]++;
  45. t=b;
  46. for(int i=1;prime[i]<=t/prime[i];i++){
  47. int p=prime[i];
  48. if(t%p==0){
  49. while(t%p==0) t/=p,mp[p]++;
  50. }
  51. }
  52. if(t>1) mp[t]++;
  53. for(auto it:mp) v.push_back(it);
  54. dfs(0,1);
  55. int p=-1,q=-1;
  56. for(int i=1;i<=cnt;i++){
  57. int x=divd[i],y=(a*b)/x;
  58. x=(a/x+1)*x;
  59. y=(b/y+1)*y;
  60. if(x<=c&&y<=d){
  61. p=x,q=y;
  62. }
  63. }
  64. cout<<p<<" "<<q<<'\n';
  65. }
  66. signed main(){
  67. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  68. initd(mxn);
  69. int __=1;cin>>__;
  70. while(__--)solve();return 0;
  71. }

总结:

a*b能被x*y整除,可以转化为:y能被a*b/gcd(a*b,x)整除

数据范围过大时可以dfs枚举因子,这样枚举的复杂度就是因子的数量

发表评论

表情:
评论列表 (有 0 条评论,193人围观)

还没有评论,来说两句吧...

相关阅读