Codeforces Edu Round 66 A-E

A. From Hero to Zero

The first step to quickly run through more than taking. Because of \ (A \% B (A> = B) <= \ FRAC} {2} {A \) . Therefore, the total complexity of not more than \ (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!

In fact, cycling is the essence of the idea of the stack, you can use \ (loop \) indicates that this layer to be recycled many times. Note that if the direct multiplication may burst \ (Long \ Long \) .

In fact, when \ (Loop> 2 ^ {32} -. 1 \) , as long as the latter \ (the Add \) are die, so long as a \ (In Flag \) recorded on the line ...

#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

Note that the data is a monotonically increasing, and it is easy to think of the shortest period must be continuous, because it becomes a positive value by the absolute value of the order must be \ (. 1, 2,. 3 .... n-\) , so every time becomes after positive, it may be the smallest, there may be greater than some of the back, because the more reduced, so the whole section will move back. We can try to enumerate each \ ([i, i + k ] \) of this range, i.e., discovery can be minimized becomes \ ((A [I + K] - A [I]) / 2 \) , i.e. all Save \ ((A [I + K] - A [I]) / 2 \) (may be rounded down). With a small heap root maintain a minimum. Because the accuracy of problems, the first can not \ (/ 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

Very clever approach, let us seek the observed value and each segment is actually $ * $ corresponding number of segments, but you can actually find a \ (ans \) is composed of:

\ (. 1 + 2 * A * B + C * =. 3 (A + B + C) + (B + C) + C \) . Essence is to find \ (k \) suffix and will seek the maximum value they add up. This can be solved directly greedy, remember \ ([1, n] \ ) of this section must be selected.

#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

Notice \ (l \) and \ (r \) is not widespread, we can pre-out from \ (l \) starting furthest to go to where (a line), note that \ (l \) may also be intermediate points. So we only need to enumerate one by one. Time complexity \ (SIZE ^ 2 \) , can be used to optimize the form of multiplication. DETAILED DESCRIPTION like \ (the LCA \) , each pre-treatment \ (L \) hops \ (2 ^ p (0 < = p <= \ lfloor log_2500000 \ rfloor) \) able to go to. The answer is essentially an enumeration of binary bit.

Time complexity \ (O (slog_2s) \) ( \ (S \) is a number range)

Note that pre-order, or \ (i \) reverse enumeration, either \ (j \) in the first condition, otherwise there is no correct branch.

#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;
}

Guess you like

Origin www.cnblogs.com/dmoransky/p/11330238.html