简单想法gcd,lcm

Description

这世界上所有的不利状况,都是当事者能力不足导致的。在这个强者生存弱者死亡的世界中,作为一个刚刚进入这个残酷世界中的你,被壁虎抓住了,壁虎是一个特别喜欢折磨人的喰种,因此他对你进行了残忍的折磨,并且在折磨你的同时为了让你保持清醒,他会让你从n开始,每次减掉x,且将每次减掉x后的数读出来(包括n本身也要读),直到这个数再次减掉x后小于0为止(不包括小于0的数)。且在最后他还要让你读出的这些数中有多少个数除以a之后余下b,如果你回答不正确,他就会杀掉你。而在这时,金木溜进来告诉你,他还需要一段时间准备,只要你再坚持,下次壁虎的折磨,他就能够救出你。

因此你是选择在壁虎残忍的折磨中死去,还是努力坚持?

Input

第一行包含四个数n,x,a,b,分别表示开始数的数字,每次减少的数,被除数与余数。

其中1<=n<=1018,1<=x<=106,1<=a<=1012,0<=b<a

Output

对于每组样例输出一个整数:你读出的数中有多少个数除a后余下b

Sample Input

1000 7 2 0

Sample Output

72
解题思路:

我们可以很快就想到想要让一个数对a取模后余下b的话只要让这个数减去b后能整除a就行了,所以对于n,x,a,b,我们可以先把b去掉。那么我们就可以把n=n-b

而对于xa的话,n-k1*x=k2*a,如果现在的n无法整除gcd(x,a)的话,我们可以发现n不论减去多少个x都不能整除a。而若能整除gcd(x,a),那么一个lcm(x,a)的范围内有且仅有一个数能整除a,因此我们可以得出ans+=n/lcm(x,a),然后把n缩小到n%lcm(x,a),即n=n%lcm(x,a)

那么在0-n之间是否还存在一个数能整除a呢(因为现在n肯定小于lcm(x,a),所以最多只有一个,也可能没有)?我们发现lcm(x,a)依旧是0-1e18的范围,因此若是一次次减去x最多需要1e12,会超时,那么看上面那个公式,n-k1*x=k2*a,我们发现可以变成n-k2*a=k1*x,因此我们可以在现在的n的范围每次减去a看是否存在一个数能整除x,这样最多1e6次即可。若存在则ans++,否则不变。

最后ans即为答案。
ac代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,x,a,b,ans;
ll gcd(ll x,ll y){
 return x%y==0?y:gcd(y,x%y);
}
ll lcm(ll x,ll y){
 return x/gcd(x,y)*y;
}
int main(){
 scanf("%lld%lld%lld%lld",&n,&x,&a,&b);
 n-=b;
 if(n%gcd(x,a)!=0){
  printf("0\n");
  return 0;
 }
 ans+=n/lcm(x,a);
 n=n%lcm(x,a);
 while(n>=0){
  if(n%x==0){
   ans++;
   break;
  }
  n-=a;
 }
 printf("%lld\n",ans);
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值