模
题目描述:
给定四个正整数a,b,c,k,回答是否存在一个正整数n,使得a*n在k进制表示下的各位的数值之和模b为c。
输入描述:
第一行一个整数T(T <= 5,000)。
接下来T行,每行四个正整数a,b,c,k(1 ≤ a ≤ 10^18; 2 ≤ k ≤ 10^18; 0 ≤ c < b ≤ 10^18)表示一个询问,所有输入都是十进制的。
输出描述:
对于每组数据输出一行,Yes表示存在,No表示不存在。
思路:
先考虑本题的一个子问题
如何表示一个数字x在k进制下的数位和?
答案:x + (1 - k)* n (其中n为未知数)
证明:对于一个数字来说,如果只有一位,那么在当前进制下
他的数位和就是x,由于当数字大于等于k时会产生进位
所以数位和会损失(k - 1),所以新的数位和一定可以表示成
上述式子
那么这个问题就变成了
ax + (1-k)y + b*z = c
其中x,y,z 均是未知数的条件下是否有解
如果有解c 一定可以被 a, (1-k), b 的最大公因子整除(扩展欧几里得)。
#include<bits/stdc++.h> #include<iostream> #include<cctype> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<stack> using namespace std; typedef unsigned long long ull; typedef long long ll; typedef pair<ll,ll> pi; #define IOS std::ios::sync_with_stdio(false) #define ls p<<1 #define rs p<<1|1 #define mod 1000000000 + 7 #define PI acos(-1.0) #define INF 1e18 #define eps 1e-8 #define N 200000 + 5 /*********************Code*********************/ ll t,a,b,c,k; int main(void){ IOS; cin>>t; while(t--){ cin>>a>>b>>c>>k; if(c%__gcd(b,__gcd(a,k-1))==0) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }