CF1312C Adding Powers 题解
题意:
多组数据。假设你正在执行以下算法:
初始时,有一个填满零的数组 $v_1, v_2, \ldots, v_n$。
该算法会多次对数组进行以下操作:
- 在第 $i$ 步(从 $0$ 开始),你可以:
- 要么选择位置 $\mathrm{pos}$ $(1 \leq \mathrm{pos} \leq n)$ 并将 $v_{\mathrm{pos}}$ 增加 $k^i$。
- 要么不选择任何位置,跳过这一步。
你可以选择算法在每一步中的行为以及何时停止。
问题是:能否在某一步后使数组 $v$ 等于给定的数组 $a$(对于每个 $j$,有 $v_j=a_j$ )?
数据范围:
$1\le T \le 10^3,~1 \le n \le 30, 1\le k \le 100, 0\le a_j \le 10^{16}$
这个题还是蛮简单的,如果目标数组能够达成,那么所有 $a_j$ 在 $k$ 进制分解后一定不存在重复出现的 $i$ 。
说到这个,顺便提醒一下, $k$ 进制下最大数码是 $k-1$ ,不要傻fufu的去 a[i] -= pwd[j]
哦!
时间复杂度 $\mathcal{O}(Tn\log M)$ ,其中 $M$ 为值域。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF ((int)(1e16 + 15))
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(233))
int n,k,cnt,vis[N],pwd[N],a[N];
void clear() {
memset(vis, 0, sizeof(vis)); memset(pwd, 0, sizeof(pwd));
}
void solve()
{
clear(); cin >> n >> k; pwd[cnt = 0] = 1;
for(cnt = 1; pwd[cnt - 1] < INF; ++cnt) {
pwd[cnt] = pwd[cnt - 1] * k;
} --cnt;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) {
for(int j = 0; a[i]; j++) {
vis[j] += a[i] % k; a[i] /= k;
}
}
char ok = false;
for(int i = 0; i <= cnt; i++) if(vis[i] > 1) ok = true;
cout << (ok ? "NO" : "YES") << '\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("check.in","r",stdin);
// freopen("check.out","w",stdout);
int Q; cin >> Q; while(Q--) solve();
return 0;
}