题目大意
给你两个正整数 n n n和 k k k,求是否存在一个序列 ( m 1 , m 2 , … , m k ) (m_1,m_2,\dots,m_k) (m1,m2,…,mk),使得
n = 3 m 1 + 3 m 2 + ⋯ + 3 m k n=3^{m_1}+3^{m_2}+\cdots+3^{m_k} n=3m1+3m2+⋯+3mk
如果存在,就输出 Y e s Yes Yes;如果不存在,就输出 N o No No。
有 t t t组数据。
1 ≤ t ≤ 1 0 5 , 1 ≤ k ≤ n ≤ 1 0 18 1\leq t\leq 10^5,1\leq k\leq n\leq 10^{18} 1≤t≤105,1≤k≤n≤1018
题解
显然,我们可以构造一个序列,序列中的 m m m值全部都为 0 0 0。如果满足 3 m 3^m 3m的和为 n n n,则序列的长度为 n n n。
因为 3 t + 3 t + 3 t = 3 t + 1 3^t+3^t+3^t=3^{t+1} 3t+3t+3t=3t+1,所以对于序列中相同的三个数 m a , m b , m c m_a,m_b,m_c ma,mb,mc,可以将这三个数用 m a + 1 m_a+1 ma+1替换。这样的话,序列的长度就减少了 2 2 2。
我们可以进行多次操作,那么序列长度就可以减少多次 2 2 2。那么,最多可以减少多少次呢?
我们可以将 n n n表示为三进制的形式,如果对于每一个 i i i,值为 i i i的 m m m的个数和 n n n的三进制的第 i i i位的数相同,则此时没有一个 m m m值存在了三次,就不能减 2 2 2了。也就是说,设 n o w now now表示 n n n的三进制数中各位数的和,则序列长度不可能小于 n o w now now。
那么,如果存在,那一定要满足两个条件:
- n n n和 k k k的差为偶数
- k ≥ n o w k\geq now k≥now
那么,这道题就解决了。
code
#include<bits/stdc++.h>
using namespace std;
int t,now;
long long n,k;
int gt(long long x){
int re=0;
while(x){
re+=x%3;x/=3;
}
return re;
}
int main()
{
scanf("%d",&t);
while(t--){
scanf("%lld%lld",&n,&k);
now=gt(n);
if(now<=k&&(n-k)%2==0) printf("Yes\n");
else printf("No\n");
}
return 0;
}