Suppose you are performing the following algorithm. There is an array v1,v2,…,vnv1,v2,…,vn filled with zeroes at start. The following operation is applied to the array several times — at ii -th step (00 -indexed) you can:
- either choose position pospos (1≤pos≤n1≤pos≤n ) and increase vposvpos by kiki ;
- or not choose any position and skip this step.
You can choose how the algorithm would behave on each step and when to stop it. The question is: can you make array vv equal to the given array aa (vj=ajvj=aj for each jj ) after some step?
The first line contains one integer TT (1≤T≤10001≤T≤1000 ) — the number of test cases. Next 2T2T lines contain test cases — two lines per test case.
The first line of each test case contains two integers nn and kk (1≤n≤301≤n≤30 , 2≤k≤1002≤k≤100 ) — the size of arrays vv and aa and value kk used in the algorithm.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤10160≤ai≤1016 ) — the array you'd like to achieve.
For each test case print YES (case insensitive) if you can achieve the array aa after some step or NO (case insensitive) otherwise.
5 4 100 0 0 0 0 1 2 1 3 4 1 4 1 3 2 0 1 3 3 9 0 59049 810
YES YES NO NO YES
大意是给定目标序列,问从起始序列(全0)能否经过若干步操作到达目标序列。对于第i次操作,可以啥都不干也可以给 某个数加上k的i次方。
考虑到可以什么都不干,且每次增加的数彼此互不相同,可以这么想:尝试把目标序列的每个数拆分成若干个k的次方(彼此互不相同)的和的形式(类似二进制拆分)如a[i]=k^p1+k^p2+....k^pn(p1!=p2!=...pn),如果不能成功拆分的话直接就能判定不能到达。然后对于每个数把其p1...pn放进一个vector然后sort,如果有两个数彼此相等则不能到达(每次操作加的数都不一样),反之可以。
详情见注释。
#include <bits/stdc++.h> using namespace std; int n,k; long long ori[35],a[35]; int main() { int t; cin>>t; while(t--) { cin>>n>>k; memset(a,0,sizeof(a)); int i; vector<int>v; for(i=1;i<=n;i++) { scanf("%lld",&ori[i]); } bool flag=1; for(i=1;i<=n;i++) { long long temp=ori[i]; int cnt=0; if(ori[i]==0)//为0则不需要任何操作 { continue; } while(temp)//拆分 { if(temp%k!=0&&(temp-1)%k!=0)//代表不能拆成k的次方和的形式 { flag=0; break; } if((temp-1)%k==0)//有k的0次方 { v.push_back(cnt);//把当前累积的变量扔进去 temp--;//减去1 cnt++; temp/=k; } else if(temp%k==0) { cnt++; temp/=k; } } if(!flag)break; } if(!flag)//必须要先判断这个 { cout<<"NO"<<endl; continue; } if(!v.size())//flag不为0的情况下如果vector是空的 { cout<<"YES"<<endl; continue; } sort(v.begin(),v.end()); for(i=0;i<v.size()-1;i++) { if(v[i]==v[i+1])//判重复 { flag=0; break; } } if(!flag) { cout<<"NO"<<endl; continue; } else cout<<"YES"<<endl; } return 0; }