洛谷 CF1999E Triple Operations 题解

洛谷 CF1999E Triple Operations 题解


题目传送门

做法

在此使用贪心

贪心做法

我们把 i i i 位置的数设为 a l a_l al
首先,将 a l a_l al 一直当作 y y y,把别的一个任意数当作 x x x 进行操作,直到 a l = 0 a_l = 0 al=0 止。接着将 a l a_l al 当作 x x x,加别的非 0 0 0 任意数当作 y y y 进行操作,直到所有数均为 0 0 0 为止。

贪心证明

其实需要一个转化。

c n t i cnt_i cnti 为将 a i a_i ai 进行多少次形如 a i = ⌊ a i 3 ⌋ a_i = \lfloor \frac{a_i}{3} \rfloor ai=3ai 的操作能使 a i a_i ai 变为 0 0 0
则原问题变为,有三种操作:

  1. c n t x + 1 cnt_x + 1 cntx+1 c n t y − 1 cnt_y - 1 cnty1
  2. c n t y − 1 ( c n t x = 0 ) cnt_y - 1 (cnt_x = 0) cnty1(cntx=0)
  3. c n t y + 1 ( c n t x = 0 ) cnt_y + 1 (cnt_x = 0) cnty+1(cntx=0)

求把所有 c n t cnt cnt 变为 0 0 0 的最小操作数。

显然,第三种操作只会让结果更劣,所以我们不做第三种操作。

我们先假设存在一个 c n t x = 0 cnt_x = 0 cntx=0,那么由于每次总和最多 − 1 - 1 1,所以最少要进行 c n t cnt cnt 的总和次操作,如果选择一个不为 0 0 0 的为止和 x x x 进行操作二,就可以在 c n t cnt cnt 的总和次操作下完成,因此这么做是最优的。

接下来,我们要证明,将一个 c n t cnt cnt 最下的数变为 0 0 0,再进行上面的操作是最优的。

由于操作1不会改变总和的大小,也就是说,前面怎么做对后面的操作次数都没有影响。因此答案就是 0 0 0 存在的最小次数 + c n t + cnt +cnt 的总和,让 0 0 0 存在的最小次数就是 c n t l cnt_l cntl,所以
A n s = c n t l + ∑ i = l r c n t r Ans = \displaystyle cnt_l + \sum_{i = l}^{r} cnt_r Ans=cntl+i=lrcntr
= 2 × c n t l + ∑ i = l + 1 r c n t r \displaystyle = 2 \times cnt_l + \sum_{i = l + 1}^{r} cnt_r =2×cntl+i=l+1rcntr

实现

c n t cnt cnt 数组直接暴力预处理即可,然后将其求前缀和 s s s ∑ i = l + 1 r c n t r = s r − s l \displaystyle \sum_{i = l + 1}^{r} cnt_r = s_r - s_l i=l+1rcntr=srsl c n t l = s l − 1 cnt_l = s_l - 1 cntl=sl1

代码

#include <iostream>
#include <cstring>
#include <algorithm>
 
using namespace std;
 
const int N = 200010;
 
int s[N];
 
int main()
{
	int T;
	scanf("%d", &T);
	
	for (int i = 1; i < N; i ++ )
	{
		int x = i;
		int cnt = 0;
		while (x)
		{
			x /= 3;
			cnt ++ ;
		}
		s[i] = s[i - 1] + cnt;
	}
	
	while (T -- )
	{
		int l, r;
		scanf("%d%d", &l, &r);
		int cnt = s[l] - s[l - 1];
		printf("%d\n", cnt * 2 + s[r] - s[l]);
	}
	return 0;
}

在这里插入图片描述

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值