Codeforces Edu Round 62 A-E

A. Detective Book

Simulation title, there are some details that need attention.

#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
const int N = 10010;
int n, a[N], ans = 0;
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) 
        scanf("%d", a + i);
        
    int tot = 1;
    while(tot <= n){
        ans++;
        int i = tot;
        tot = max(tot, a[tot]);
        while(++i <= tot){
            tot = max(tot, a[i]);
        }
        tot++;
    } 
    printf("%d\n", ans);
    return 0;
}

B. Good String

greedy.

  1. Find the front to back first \ (> \) , put back all deleted (if not deleted, the results will not be better, in front of the character can not handle)
  2. Looking forward from the first \ (<\) , put in front of all deleted, ditto

Find these two operations can be optimized.

#include <cstdio>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 110;
int n;
char s[N];
int main(){
    int T; scanf("%d", &T);
    while(T--){
        scanf("%d%s", &n, s + 1);
        int l = 1, r = n;
        while(s[l] != '>') l++;
        while(s[r] != '<') r--;
        printf("%d\n", min(l - 1, n - r));
    }
    return 0;
}

C. Playlist

greedy.

We now before the problem solution set \ (cnt \) is the total length of the songs chosen, \ (min \) for the selected song smallest good degree, that \ (ans = min * cnt \ )

Each song Press (b [i] \) \ (better degree) in descending order. I.e., to ensure that \ (b [i]> = b [i + 1] (1 <= i <n) \)

We first consider no song limit, you can select an unlimited number of songs.

Every election of a better degree must be continuous period of \ ([1, r] \ ) , that is, \ ([1, r] \ ) songs in the interval must all choose.


Proof: reductio ad absurdum

If not filled, then there is a song \ (I \) satisfies \ (B [I]> = min \) . If you select the song, then \ (minn \) will not change, and the provisions of title \ (t [i]> = 1 \) , ie after adding \ (cnt \) must become large, so the answer will be more excellent.


So, assuming no restrictions, we need only consider each descending from a song, put it, to find the optimal answer, due in turn to consider, considering the current set of songs for the \ (i \) , \ (Minn = b [i] \) (since descending order), \ (cnt \) also increased by \ (t [i] \) , can be successfully solved.


If there are restrictions?

We can be deleted from the selected songs, because the songs have been selected to meet the \ (b [i]> = Minn \) , even if you delete \ (minn \) value will not change. So we want to choose from a selected \ (t [i] \) (length) to a minimum, this process can be maintained with a small heap root.

PS: Since the time of writing that you want to dynamically maintain minimum, so write two small root pile, actually only one, the other can be sorted, but in fact, the complexity does not change, because the fast row is \ (O (nlogn) \) ...

#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 300010;
int n, k, t[N], b[N];
priority_queue<PII> q;
priority_queue<int, vector<int>, greater<int> > minn; 
int main(){
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++){
        scanf("%d%d", t + i, b + i);
        q.push(make_pair(b[i], t[i]));
    }
    LL cnt = 0, ans = -1;
    int tot = 0;
    while(!q.empty()){
        PII u = q.top(); q.pop(); tot++;
        minn.push(u.second);
        cnt += u.second;
        ans = max(ans, cnt * u.first);
        if(tot == k) cnt -= minn.top(), minn.pop(), tot --;
    }
    printf("%lld\n", ans);
    return 0;
}

D. Minimum Triangulation

Taking into account only do the triangle with the point on the side edge. To split into \ (n - 2 \) triangles.

Can make two choices can be reached Requirements:

  1. Find a center of gravity \ (I \) , and further connected to each point. The answer is \ (i * x * y + i * y + z + ... \)
  2. In other root, each transfer center, the answer is \ (x * y * z + y * z * a + ... \)

Minimum weight requirements, options \ ((1) \) and the center of gravity is selected from the group \ (1 \) can, because of the change in the root is the root of all $> $ = 1, the value is not necessarily excellent. Because I am too weak to finish the title to see the solution to a problem I realize that general term formula, as konjac I do not understand ...

#include <cstdio>
#include <iostream>
using namespace std;
int n, res = 0;
int main(){
    scanf("%d", &n);
    for(int i = 2; i < n; i++) 
        res += i * (i + 1);
    printf("%d\n", res);
    return 0;
}

E. Palindrome-less Arrays

Autistic, I see senseless.

Taking into account if there is a palindromic odd, there must be a length \ (3 \) a palindromic substring, as long as we \ (a [i]! = A [i + 2] \) to. This time we parity resolved by \ (DP \) pretreatment period \ (- 1 \) processing of a continuous string, (with \ (DP \) processing) can be further multiplied.

(To understand all of the above solution to a problem, do not think ... adorable new)

Set \ (f [i] [0/1 ] \) consecutive intermediate \ (I \) a \ (- 1 \) , both ends of the same number \ (/ \) different schemes Number

Border: \ (F [0] [0] =. 1, F [0] [. 1] = 0 \)

\(f[i][0] = (k - 2) * f[i - 1][0] + f[i - 1][1]\)

That is, from the \ (i - 1 \) consecutive \ (--1 \) , plus a number, just to meet this character \ (= \!) At the beginning and end of the can, and not the beginning and end Like, it is \ (k - 2 \) . Also available from \ (i - 1 \) the same over the two ends, the only solution is

\(f[i][1] = (k - 1) * f[i - 1][0]\)

Empathy.

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 200010, MOD = 998244353;
int n, k, a[N], b[N], l1 = 0, l2 = 0, f[N][2];
int inline mul(int x, int y){
    return ((LL)x * y) % MOD;
}
int inline add(int x, int y){
    return ((LL)x + y) % MOD;
}
int power(int q, int m){
    int res = 1;
    while(m){
        if(m & 1) res = (LL)res * q % MOD;
        q = (LL)q * q % MOD;
        m >>= 1;
    }
    return res;
}
int work(int w[], int len){
    if(n == 0) return 1;
    int l = 1, r = len;
    while(l <= len && w[l] == -1) l++;
    if(l == len + 1) return mul(k, power(k - 1, len - 1));
    while(r && w[r] == -1) r--;
    int res = mul(power(k - 1, l - 1), power(k - 1, len - r));
    int first = l;
    for(l = first + 1; l <= r; l++){
        if(w[l] == -1) continue;
        res = mul(res, f[l - first - 1][w[first] == w[l]]);
        first = l;
    }
    return res;
}
int main(){
    scanf("%d%d", &n, &k);
    f[0][0] = 1;
    for(int i = 1; i <= n; i++){
        f[i][0] = add(mul(k - 2, f[i - 1][0]), f[i - 1][1]);
        f[i][1] = mul(k - 1, f[i - 1][0]);
    }
    for(int i = 1; i <= n; i++) {
        if(i & 1) scanf("%d", &a[++l1]);
        else scanf("%d", &b[++l2]);
    }
    printf("%d\n", mul(work(a, l1), work(b, l2)));
    return 0;
}

Guess you like

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