Codeforces Round #701 (Div. 2) A ~ F ,6题全,超高质量良心题解【每日亿题】2021/2/13

整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


怎么这么多人AK呀 … 确实挺简单的 (●ˇ∀ˇ●) 考到了很多常用技巧,一堆智商检测题,简直好评hhh
不过怎么全是签到题呀,确实比较考察思维hhh但是比赛过的人却很少 ~ 以前前几题都是能过一万五来着,这次只有几千…

比赛链接:https://codeforces.com/contest/1485

A - Add and Divide

Problem A Add and Divide
在这里插入图片描述
Translation
给定两个正整数 a a a, b b b ,你可以进行两种操作:

  • 使得 a = ⌊ a b ⌋ a=\lfloor\cfrac{a}{b}\rfloor a=ba
  • 使得 b = b + 1 b = b + 1 b=b+1

请问最少多少次操作,使得 a = 0 a=0 a=0

Word
在这里插入图片描述

Solution

签到题 ~

之前做过这种题目,链接:2021年洛谷一月月赛(Div1、Div2,6题)全部题解 C题,比这个难多了 ~

但是万变不离其宗,那道题同样有两个操作,加一或者 × 2 \times 2 ×2 ,最小费用修改,使得整个序列满足一个条件,需要套一个二分加DP。

中心思想还是分析性质。我们发现 + + + 操作前期比 × \times × 收益更大,后期 × \times × 操作比 + + + 操作收益更大,由于乘的话是指数级增长,所以那么数据是 1 0 9 10^9 109 ,实际的操作次数也是常数级别的,所以我们可以暴力。这道题仅要求将 a a a 除到 0 0 0,我们仅需将 b b b 加到 10 10 10 即可,然后暴力计算。

其实可以简单地证明一下,为什么到 10 10 10 一定ok,实际上一次加操作,最后的总贡献是你乘的次数,如果当你乘一次的贡献就已经超过了乘的次数,也就是说乘的贡献此时一定超过了加的贡献,所以简单算一下,我们发现 log ⁡ 10 1 0 9 = 9 \log_{10}10^9=9 log10109=9, 所以只需要加到10即可 ~

Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;
typedef long long ll;
typedef int itn;
const int N = 5007;
const ll INF = 4e18;

int n, m, t;
ll a, b;

void solve()
{
   
    scanf("%lld%lld", &a, &b);
    if(a == 0) {
   
        puts("0");
        return ;
    }
    ll res = INF, ans;
    ll cnt = 0;
    ll B = b;
    if(b == 1) b ++ , cnt ++ ;
    for(; b <= 10; ++ b) {
   

        ans = 0;
        cnt ++ ;
        ll tmp_a = a;
        while(tmp_a) {
   
            tmp_a /= b;
            ans ++ ;
        }
        ans += cnt;
        ans -- ;
        if(ans < res) res = ans;
    }
    if(B > 10) {
   
        ans = 0;
        while(a) {
   
            a /= B;
            ans ++ ;
        }
    }
    res = min(res, ans);
    printf("%lld\n", res);
    return ;
}

int main()
{
   
    scanf("%d", &t);
    while(t -- ) {
   
        solve();
    }
}

B - Replace and Keep Sorted

Problem B Replace and Keep Sorted

在这里插入图片描述
Translation

对于一个正整数 k k k ,规定两个序列是 k k k 相似序列” 需要满足以下要求:

  • 两个序列严格递增
  • 两个序列有相同的长度
  • 两个序列的元素的取值 ∈ [ 1 , k ] \in[1,k] [1,k]
  • 两个序列仅有一个位置的元素不同

给定一个正整数 k k k,一个严格递增的序列 a a a ,将会有 q q q 次询问,每次询问一个区间 l l l r r r ,你的任务是每次输出有多少种 b b b 序列是序列 a l , a l + 1 , a l + 2 ⋯   , a r a_l,a_{l+1},a_{l+2}\cdots,a_r al,al+1,al+2,ar k k k 相似序列”

Word
在这里插入图片描述

Solution

签到题 ~

注意一个重要的性质:严格递增

因为元素的取值只能是 [ 1 , k ] [1,k] [1,k] ,并且两个序列必须只能有一个不同的元素,由于序列一定严格递增,求总的方案数,实际上对于每一个序列来说,每次只能有一个位置不同,而对于这个位置来说,手算一下发现,对于每一个区间里的数,一共有 a [ i + 1 ] − a [ i − 1 ] − 2 a[i+1]-a[i-1]-2 a[i+1]a[i1]2 种选法,对于区间的边界来说,一共有 a [ i + 1 ] − a [ i − 1 ] − 2 a[i+1]-a[i-1]-2 a[i+1]a[i1]2 种选法,设每一个位置 i i i 的选法就是 i i i 的权值,由加法原理可知,总方案数就是区间权值和,所以我们直接使用一个前缀和维护一下即可。

Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;
typedef long long ll;
typedef int itn;
const int N = 2e5 + 7;
const ll INF = 4e18;

int n, m, t, q, k;

ll val[N], a[N];
ll sum[N];

int main()
{
   
    scanf("%d%d%d", &n, &q, &k);
    for(int i = 1; i <= n; ++ i) {
   
        scanf("%d", &a[i]);
    }
    a[0] = 1, a[n + 1] = k;
    for(int i = 1; i <= n; ++ i) {
   
        val[i] = a[i + 1] - a[i - 1] - 2;
        sum[i] = sum
  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁凡さん

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值