453 字
2 分钟
Codeforces Round 964 (Div. 4) E 题解
2024-08-08

Codeforces Round 964 (Div. 4) E - Triple Operations

题目翻译#

Ivy 在黑板上写下了从 llrr 的所有整数(包含 ll, rr)。

她执行以下操作:

  • 在黑板上选择两个数字 xxyy ,擦除它们,并在它们的位置写上数字 3x3xy3\lfloor \frac{y}{3} \rfloor (此处 \lfloor \bullet \rfloor 表示向下舍入到最接近的整数)。

Ivy 需要的最少操作数是多少才能使黑板上的所有数字相等 00? 我们有一个证明,这总是可能的。

样例数量 tt (1t1041 \leq t \leq 10^4), 1l<r21051 \leq l < r \leq 2 \cdot 10^5

解题思路#

不难发现,想要将其全部变为 0,首先需要 xx 总是等于 00 。 于是子问题变为:

  1. 如何最快获得一个 00
  2. 在完成第一步后,在 x=0x = 0 的情况下, 最快全部变为 0 需要 y /= 3 多少次?

由于数据范围为 1l<r21051 \leq l < r \leq 2 \cdot 10^5, 我们可以预处理每一个数循环除以 33 变为 00 的次数 did_i,再求出前缀和数组sum,便可以通过 sum[b] - sum[a - 1] 求出全部变为 0 的次数。

在获取第一个 00 的过程中,yy 会被 y *= 3 dld_l 次,最终需要把它除回去,答案应当加上 dld_l

时间复杂度 O(2e5)O(2e5)

完整代码#

#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) - Solution Discussion - Shayan

Codeforces Round 964 (Div. 4) E 题解
https://darkmodest.github.io/posts/solutions/cf1999e/
作者
Dark_Modest
发布于
2024-08-08
许可协议
CC BY-NC-SA 4.0