Codeforces Round #701 (Div. 2) A~C 题解

写在前边

链接:Codeforces Round #701 (Div. 2)
数学场,题目描述简单粗暴,思路很妙,代码短的不行,都是好神奇的一些题目。

A. Add and Divide

链接:A题链接

题目大意:

给定两个正整数,我们可以进行两个操作:

  • a=ab
  • b=b+1
    最终目标是找到使a变成0的最小操作次数

思路

因为b每次只会变动1,所以最开始思路就是,如果我们可以提前大体找到一个操作次数,我们在这个操作次数内进行枚举,而b每次操作只会变动1,所以假设一共有sum次操作,如果我们可以有n次让b1,然后b变成了b+n,然后让a不断的除b直到为0,假设有m次操作,那么答案就是m+n次操作了,那么怎么才能找到这个sum呢,可以看数据范围,我们可以估计最差的情况,最差的情况就是当b=1a=109的时候,这时候我们首先要做的就是让b+1,然后再让a不断的除b,直到为0,而这最多需要log2(109)=29次,所以!经过分析最差情况也就进行30次操作左右,即m+n<31所以我们只需要枚举到31即可,最坏情况O(log2a)

代码:

#include <iostream>

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>

using namespace std;

#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;

void solve() {
    int a, b, res = 35;
    cin >> a >> b;
    if (a < b) {
        puts("1");
        return;
    }

    for (int i = (b == 1 ? 1 : 0); i <= 30; i++) { //枚举多少次 最坏情况下就有30次
        int tempa = a, tempres = i;
        int tempb = b + i;
        
        while (tempa) {
            tempa /= tempb;
            tempres++;  
        }
        res = min(res, tempres);
    }

    cout << res << endl;
}

int main()
{
    //ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    scanf("%d", &t); 
    while (t--) {
        solve();
    }
    system("pause");
    return 0;
}

B. Replace and Keep Sorted

链接:B题链接

题目大意:

定义两个互为ksimilar的数组:

  • 都是严格单调递增
  • 有相同的长度
  • 它们的元素范围[1,k]
  • 它们只有一个数不同。

现在给定一个数组a,并且给定一个区间[l,r],那么ksimilar中的一个数组b1就是[al,al+1,...,ar],长度为len=lr+1 那么另一个ksimilar数组b2就是可以从[1,k]中选len个数,并且只与b1有一个数不同的数组,问有多少个这样的数组b2

思路

首先想到可以挨个枚举每一个位置可以选多少个数,那么最终答案就是每一个位置可以选的数之和,但是这样数据范围就是O(qn)明显会超时,所以就想能不能在O(1)复杂度之内就能判断出一个区间中所有的可能,第l个位置的数可以选a[l+1]2个,第r个位置的数可以选ka[r1]1个,对于(l,r)(注意是开区间!)能选多少个我们可以用前缀和处理,前缀和就是每一个区间可以选择的数的个数,时间复杂度就降为了O(q).

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>

using namespace std;

#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;

const int N = 1e5 + 10;
int a[N], b[N];

void solve() {
    int n, k, q;
    scanf("%d%d%d", &n, &q, &k);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);

    a[n + 1] = k + 1;
    for (int i = 1; i <= n; i++) {
        b[i] += a[i + 1] - a[i - 1] - 2;
        b[i] += b[i - 1];
    }

    while (q--) {
        LL res = 0;
        int l, r;
        scanf("%d%d", &l, &r);
        res += b[r - 1] - b[l];  //开区间
        res += k - a[r - 1] - 1; //右边    
        res += a[l + 1] - 2; //左边
        printf("%d\n", res);
    }
}

int main()
{
    //ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    solve();

    return 0;
}

C. Floor and Mod

链接:C题链接

题目大意:

给定下下xy,现在要求求一个数对(a,b),使得ab=amodb, 要求a[1,x], b[1,y]

思路

首先暴力肯定不行,所以想能不能用O1直接求出来,那只要推公式了,让ab=amodb=k,所以推出a=kb+k(b>k),又因为b>k,可以推出k2<kb+k=ax,所以kx,所以现在求出了k的范围k[1,x],现在要做的就是对于每一个固定的k,如果我们可以推出a或者b数的范围,那么就可以求出数对(a,b)可取的个数了,对于b,已知b>k, 1by,根据 kb+k=ax,得出bx/k1,因此得出b的个数就是max(0,min(y,x/k1)k)

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>

using namespace std;

#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;

void solve() {
    LL x, y;
    cin >> x >> y;

    LL res = 0;
    for (LL k = 1; k * k <= x; k++) {
        res += max(0LL, min(y, x / k - 1) - k);
    }

    cout << res << endl;
}

int main()
{
    //ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    scanf("%d", &t); 
    while (t--) {
        solve();
    }
    system("pause");
    return 0;
}
posted @   Xxaj5  阅读(228)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示