453 字
2 分钟
Codeforces Round 964 (Div. 4) E 题解
Codeforces Round 964 (Div. 4) E - Triple Operations
题目翻译
Ivy 在黑板上写下了从 到 的所有整数(包含 , )。
她执行以下操作:
- 在黑板上选择两个数字 和 ,擦除它们,并在它们的位置写上数字 和 (此处 表示向下舍入到最接近的整数)。
Ivy 需要的最少操作数是多少才能使黑板上的所有数字相等 ? 我们有一个证明,这总是可能的。
样例数量 (), 。
解题思路
不难发现,想要将其全部变为 0,首先需要 总是等于 。 于是子问题变为:
- 如何最快获得一个 ?
- 在完成第一步后,在 的情况下, 最快全部变为 0 需要
y /= 3多少次?
由于数据范围为 , 我们可以预处理每一个数循环除以 变为 的次数 ,再求出前缀和数组sum,便可以通过 sum[b] - sum[a - 1] 求出全部变为 0 的次数。
在获取第一个 的过程中, 会被 y *= 3 次,最终需要把它除回去,答案应当加上 。
时间复杂度 。
完整代码
#include <bits/stdc++.h>using namespace std;#define int long long#define endl '\n'const int N = 2e5+5;int d[N], sum[N];
int gd(int x){ int cnt = 0; while(x){ cnt++; x /= 3; } return cnt;}
signed main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
for(int i = 1; i <= N - 1; i++){ d[i] = gd(i); sum[i] = sum[i - 1] + d[i]; }
int cases; cin >> cases; for(int ii = 1; ii <= cases; ii++){ sum[0] = 0; int l, r; cin >> l >> r; cout << sum[r] - sum[l - 1] + d[l] << endl; } return 0;}参考
Codeforces Round 964 (Div. 4) E 题解
https://darkmodest.github.io/posts/solutions/cf1999e/