Codeforces Edu Round 66 A-E

A. From Hero to Zero

通过取余快速运行第一步即可。由于\(a \% b (a >= b) <= \frac{a}{2}\)。所以总复杂度不超过\(O(log_2n)\)。

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long LL;
int main(){
    int T; scanf("%d", &T);
    while(T--){
        LL n, k, ans = 0;
        scanf("%lld%lld", &n, &k);
        while(n){
            if(n % k) ans += n % k, n -= n % k;
            if(n)n /= k, ans++;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

B. Catch Overflow!

循环本质其实是栈的思想,可以用\(loop\)表示这层要循环多少次。注意如果直接乘可能爆\(long\ long\)。

其实当\(loop > 2 ^ {32} - 1\),后面的只要有\(add\)都不行了,所以只要用个\(flag\)记录就行了...

#include <cstdio>
#include <iostream>
#include <string>
#include <stack>
using namespace std;
typedef long long LL;
const LL INF = (1ll << 32) - 1;
LL n = 0, loop = 1;
stack<int> s;
string ch;
int x, flag = 0;
int main(){
    ios::sync_with_stdio(false);
    int T; cin >> T;
    while(T--){
        cin >> ch;
        if(ch == "add"){
            if(loop > INF){
                cout << "OVERFLOW!!!" << endl;
                return 0;
            }
            n += loop;
        }else if(ch == "for"){
            cin >> x;
            if(loop > INF) {
                flag++;
                continue;
            }
            s.push(x);
            loop *= x;
        }else if(ch == "end"){
            if(flag) {
                flag --;
                continue;
            }
            loop /= s.top();
            s.pop();
        }
        if(n > INF){
            cout << "OVERFLOW!!!" << endl;
            return 0;
        }
    }
    cout << n << endl;
    return 0;
}

C. Electrification

注意数据是单调递增的,所以容易想到最短的一段必然是连续的,因为通过绝对值变成正的值顺序一定是\(1, 2, 3....n\),所以每次变成正的后,它可能是最小的,也有可能大于后面的一些,因为减的多了,所以整个区间会往后移动。我们可以尝试枚举每一个\([i, i + k]\)的这个区间,发现能使最小的即变为\((a[i + k] - a[i]) / 2\),也就是全部都减\((a[i + k] - a[i]) / 2\)(可以向下取整)。可以用小根堆维护最小值。由于精度问题,第一个可以不用\(/2\)。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
const int N = 200010;
int n, k, a[N];
priority_queue<PII, vector<PII>, greater<PII> > q;
int main(){
    int T; scanf("%d", &T);
    while(T--){
        while(q.size()) q.pop();
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++)
            scanf("%d", a + i);
        for(int i = 1; i + k <= n; i++)
            q.push(make_pair(a[i + k] - a[i], (a[i] + a[i + k]) / 2));
        printf("%d\n", q.top().second);
    }
    return 0;
}

D. Array Splitting

非常巧妙的做法,观察到让我们求的值其实是每一段的和$ * $ 相应的段数,但其实可以发现,一个\(ans\)的组成为:

\(1 * A + 2 * B + 3 * C = (A + B + C) + (B + C) + C\)。实质上就是找到\(k\)个后缀和,将他们加起来求最大值。这样直接贪心求解即可,记得\([1, n]\)这个区间必须选。

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 300010;
typedef long long LL;
int n, k, a[N];
LL ans, sum[N];
int main(){
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++)
        scanf("%d", a + i);
    for(int i = n; i; i--)
        sum[i] = sum[i + 1] + a[i];
    sort(sum + 2, sum + 1 + n);
    ans = sum[1];
    for(int i = n; i >= n - k + 2; i--) ans += sum[i];
    printf("%lld\n", ans);
    return 0;
}

E. Minimal Segment Cover

注意到\(l\)和\(r\)的范围并不大,我们可以预处理出从\(l\)出发最远能到哪里(一条线段),注意\(l\)也可以是中间点。这样我们只需要逐个枚举即可。时间复杂度\(SIZE ^ 2\),可以用倍增的形式优化。具体方式很像\(LCA\),预处理每个\(l\)跳\(2 ^ p(0 <= p <= \lfloor log_2500000 \rfloor)\)能到哪里即可。本质上就是枚举答案的二进制位即可。

时间复杂度\(O(slog_2s)\)(\(s\)是数字范围)

注意预处理顺序,要么\(i\)倒序枚举,要么\(j\)在第一个条件,否则没有正确的转移。

#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
const int N = 200010, SIZE = 500010, L = 19;
int n, m, maxS = -1, f[SIZE][L];
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++){
        int l, r; scanf("%d%d", &l, &r);
        f[l][0] = max(f[l][0], r);
        maxS = max(maxS, r);
    }
    for(int i = 1; i <= maxS; i++)
        f[i][0] = max(f[i][0], f[i - 1][0]);

    for(int j = 1; j < L; j++)
        for(int i = 0; i <= maxS; i++)
            f[i][j] = f[f[i][j - 1]][j - 1];

    for(int i = 1; i <= m; i++){
        int x, y, ans = 0;  scanf("%d%d", &x, &y);
        for(int i = L - 1; ~i; i--)
            if(f[x][i] < y) x = f[x][i], ans |= 1 << i;
        if(f[x][0] >= y) printf("%d\n", ans + 1);
        else puts("-1");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/dmoransky/p/11330238.html

时间: 2024-08-30 05:40:53

Codeforces Edu Round 66 A-E的相关文章

Codeforces Edu Round 66 (Rated for Div. 2)

题面很短,质量很好. 题目链接:https://codeforces.com/contest/1175 A: 给定n,k,有两种操作:1) n--,2) 当n%k==0时,可以n/=k.问最少多少步把n变成0. 傻逼题. 1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #de

CFEducational Codeforces Round 66题解报告

CFEducational Codeforces Round 66题解报告 感觉丧失了唯一一次能在CF上超过wqy的机会QAQ A 不管 B 不能直接累计乘法打\(tag\),要直接跳 C 考虑二分第\(k\)小的值 那么问题就变成了 每一个数变成了\([x-mid,x+mid]\)的一段区间,如果有一个位置被覆盖了超过\(k\)次 那么\(mid\)一定合法 类似括号匹配 每次碰到左端点就贡献+1 右端点就统计答案然后-1 维护答案的同时顺便维护位置就好了 #include<cstdio>

Codeforces Beta Round #91 (Div. 1 Only) E. Lucky Array

E. Lucky Array Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467are not. Petya has an arra

CodeForces Beta Round #1

Codeforces Beta Round #1 A. Theatre Square [题意]一个n*m的矩形广场,用a*a的方形石板铺设,问最少需要多少块石板能铺满广场. [思路]水题,从n方向来看能能够铺设ceil(n/a)块,从m方向来看能能够铺设ceil(m/a)块,总共有ceil(n/a)*ceil(m/a)块. 1 /* 2 ** CodeForces 1A Theatre Square 3 ** Created by Rayn @@ 2014/05/18 4 */ 5 #inclu

图论/暴力 Codeforces Beta Round #94 (Div. 2 Only) B. Students and Shoelaces

题目传送门 1 /* 2 图论/暴力:这是个连通的问题,每一次把所有度数为1的砍掉,把连接的点再砍掉,总之很神奇,不懂:) 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #include <cmath> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3

Codeforces Beta Round#2

Codeforces Beta Round#2 http://codeforces.com/contest/2 A 模拟题 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 map<string,ll>mp; 6 struct sair{ 7 string str; 8 int id; 9 ll num; 10 }a[1005]; 11 12 bool cmp(sair a,sa

Codeforces Beta Round #7

Codeforces Beta Round #7 http://codeforces.com/contest/7 A 水题 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define sqr(x) ((x)*(x)) 6 #define maxn 1000010 7 typedef long lon

Codeforces Beta Round #9 (Div. 2 Only)

Codeforces Beta Round #9 (Div. 2 Only) http://codeforces.com/contest/9 A gcd水题 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define sqr(x) ((x)*(x)) 6 #define maxn 1000010 7

Codeforces Beta Round #12 (Div 2 Only)

Codeforces Beta Round #12 (Div 2 Only) http://codeforces.com/contest/12 A 水题 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define sqr(x) ((x)*(x)) 6 #define maxn 1000010 7 t