【题解】[CCO2021] Weird Numeral System
敢想敢写。。。
我们直接定义状态 \(f_{i}\) 表示数 \(i\) 能否被表示出来。
然后我们枚举最低位 \(a_x\),如果 \(k | (i - a_{x})\) 就可以从 \(f_{(i - a_{x}) / k}\) 转移到 \(f_{i}\)。因为次低位一定是 \(k\) 的倍数,所以当前 \(i\) 减去 \(a_x\) 一定是 \(k\) 的倍数。
由于 \(a_{x}\) 可以是负数,所以 \((i -a_{x})/k\) 可以等于 \(i\),相当于自己转移自己,会无线递归下去,这种情况特判掉。
貌似状态数是 \(10^{18}\) ,转移也有 \(800\),但无用状态非常多,并且如果 \(D\) 比较大,那么大概率可以表示任意一个数,而我们搜到一个方案就结束了。
#define N 1005
int k, n, m, q, a[N];
unordered_map<LL, bool> f;
vector<int>ans;
bool calc(LL x){
if(f.count(x))return false;
f[x];
rp(i, n)if(a[i] == x){
ans.pb(a[i]);
return true;
}
rp(i, n){
if((x - a[i]) % k == 0 && (x - a[i]) / k != x && calc((x - a[i]) / k)){
ans.pb(a[i]); return true;
}
}
return false;
}
int main() {
read(k, q, n, m);
rp(i, n)read(a[i]);
while(q--){
LL x; read(x);
f.clear(), ans.clear();
if(calc(x)){
go(y, ans)printf("%d ", y); el;
}
else puts("IMPOSSIBLE");
}
return 0;
}