Codeforces Round #635 (Div. 1)

Portal

A. Linova and Kingdom

Topic:
Given a tree with \ (1 \) as the root, we now need to select \ (k \) nodes as black dots, and the contribution of one black dot is the white dot passing from him to the root node Quantity.
Ask what is the maximum sum of blackpoint contributions.

Ideas:

  • The most straightforward idea is that the black point is definitely the deeper the point, the better, and there is such a property: suppose we select a point, then all the descendants of that point will also be selected.
  • The contribution of a black dot is its depth minus the number of black dots in the root path.
  • Directly follow the above thoughts and greedy, not thinking, consider transforming the calculation method of contribution: when we subtract the number of black dots, we reduce it at its ancestor node. In other words, each black dot will subtract its subtree \ (size \) .
  • Then sort all points according to \ (deep-size \) , greedy to choose from big to small.

Because all the subtrees selected at a point are also selected, and obviously the \ (deep-size \) of the subtree is larger, it is easy to prove that this greedy is correct.

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/4/15 22:36:55
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
 
int n, k;
vector <int> G[N];
int d[N], sz[N];
 
void dfs(int u, int fa) {
    d[u] = d[fa] + 1;
    sz[u] = 1;
    for(auto v : G[u]) if(v != fa) {
        dfs(v, u);
        sz[u] += sz[v];
    }   
}
 
void run() {
    cin >> n >> k;
    for(int i = 1; i < n; i++) {
        int u, v; cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);   
    }
    dfs(1, 0);
    vector <int> v;
    for(int i = 1; i <= n; i++) {
        v.push_back(d[i] - sz[i]);   
    }
    sort(all(v));
    reverse(all(v));
    ll ans = 0;
    for(int i = 0; i < k; i++) ans += v[i];
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}

B. Xenia and Colorful Gems

Enumerate one dimension, and then directly greedy the other two dimensions.
The code is a bit messy. .

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/4/15 22:47:16
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
//#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
int na, nb, nc;
 
ll a[N], b[N], c[N];
 
ll calc(int x, int y, int z) {
    if(x && y && z && x <= na && y <= nb && z <= nc)
        return (a[x] - b[y]) * (a[x] - b[y]) + (a[x] - c[z]) * (a[x] - c[z]) + (b[y] - c[z]) * (b[y] - c[z]);
    return 8e18;
}
 
ll calc_a(int y, int z) {
    int t = lower_bound(a + 1, a + na + 1, b[y]) - a;
    ll res = 9e18;
    res = min(res, calc(t, y, z));
    res = min(res, calc(t - 1, y, z));
    t = lower_bound(a + 1, a + na + 1, c[z]) - a;
    res = min(res, calc(t, y, z));
    res = min(res, calc(t - 1, y, z));
    return res;
}
 
ll calc_c(int x, int y) {
    int t = lower_bound(c + 1, c + nc + 1, b[y]) - c;
    ll res = 9e18;
    res = min(res, calc(x, y, t));
    dbg(x, y, t, res);
    res = min(res, calc(x, y, t - 1));
    t = lower_bound(c + 1, c + nc + 1, a[x]) - c;
    res = min(res, calc(x, y, t));
    res = min(res, calc(x, y, t - 1));
    return res;
}
 
ll calc_b(int x, int z) {
    int t = lower_bound(b + 1, b + nb + 1, c[z]) - b;
    ll res = 9e18;
    res = min(res, calc(x, t, z));
    res = min(res, calc(x, t - 1, z));
    t = lower_bound(b + 1, b + nb + 1, a[x]) - b;
    res = min(res, calc(x, t, z));
    res = min(res, calc(x, t - 1, z));
    return res;   
}
 
void run() {
    cin >> na >> nb >> nc;
    for(int i = 1; i <= na; i++) cin >> a[i];
    for(int i = 1; i <= nb; i++) cin >> b[i];
    for(int i = 1; i <= nc; i++) cin >> c[i];
    sort(a + 1, a + na + 1);
    sort(b + 1, b + nb + 1);
    sort(c + 1, c + nc + 1);
    ll ans = 9e18;
    for(int i = 1, t; i <= na; i++) {
        t = lower_bound(b + 1, b + nb + 1, a[i]) - b;
        if(t <= nb) ans = min(ans, calc_c(i, t));
        if(t > 1) ans = min(ans, calc_c(i, t - 1));
        t = lower_bound(c + 1, c + nc + 1, a[i]) - c;
        if(t <= nc) ans = min(ans, calc_b(i, t));
        if(t > 1) ans = min(ans, calc_b(i, t - 1));
    }
    for(int i = 1, t; i <= nb; i++) {
        t = lower_bound(a + 1, a + na + 1, b[i]) - a;
        ans = min(ans, calc_c(t, i));
        ans = min(ans, calc_c(t - 1, i));
        t = lower_bound(c + 1, c + nc + 1, b[i]) - c;
        ans = min(ans, calc_a(i, t));
        ans = min(ans, calc_a(i, t - 1));
    }
    for(int i = 1, t; i <= nc; i++) {
        t = lower_bound(b + 1, b + nb + 1, c[i]) - b;
        ans = min(ans, calc_a(t, i));
        ans = min(ans, calc_c(t - 1, i));
        t = lower_bound(a + 1, a + na + 1, c[i]) - a;
        ans = min(ans, calc_b(t, i));
        ans = min(ans, calc_b(t - 1, i));
    }
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

C. Kaavi and Magic Spell

Title:
Given the string \ (S, T \) , there is now an empty string \ (A \) , and then perform the following operations each time:

  • Select and delete the first character of \ (S \) , then insert it before or after \ (A \) .

Now ask how many ways to make the string \ (T \) the prefix of the string \ (A \) .

Idea:
Fill the \ (T \) string with \ (* \) to the same length as \ (S \) , the question is converted into a prefix for \ (T \) , how many matching methods does \ (S \) have? .
Note that there is a property: when matching any section of \ (T \) , we will only use a prefix of \ (S \) .
Then we directly run an interval \ (dp \) , which means that the number of solutions matching \ (T [l, r] \) , directly according to \ (s [r-l + 1] \) \ (O (1) \) Just transfer.
The final answer is \ (\ sum_ {i \ geq m} {dp_ {1, i}} \) .
See code for details:

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/4/16 9:06:01
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 3000 + 5, MOD = 998244353;
 
int n, m;
char s[N], t[N];
int dp[N][N];
 
int solve(int l, int r) {
    if(l > r) return 1;
    if(dp[l][r] != -1) return dp[l][r];
    int k = r - l + 1;
    int res = 0;
    if(l > m || s[k] == t[l]) res += solve(l + 1, r);
    if(r > m || s[k] == t[r]) res = (res + solve(l, r - 1)) % MOD;
    return dp[l][r] = res;
}
 
void run() {
    cin >> (s + 1) >> (t + 1);
    n = strlen(s + 1), m = strlen(t + 1);
    memset(dp, -1, sizeof(dp));
    int ans = 0;
    for(int i = m; i <= n; i++) {
        ans = (ans + solve(1, i)) % MOD;   
    }
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/12710644.html