Educational Codeforces Round 89 (Rated for Div. 2)

傳送門
視頻題解
ios

A. Shovels and Swords

貪心。每次儘量取較多那一邊便可。
寫法上能夠加速,\((2,1),(1,2)\)這種能夠看做\((3,3)\),只取\((1,2)\)這種解個方程便可。
代碼以下:

ide

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/11 22:36:15
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#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;

void run() {
    int a, b; cin >> a >> b;
    if (a > b) swap(a, b);
    int x = min(b / 2, min(a, b - a));
    b -= 2 * x;
    a -= x;
    int ans = x;
    int c = min(a, b);
    ans += c / 3 * 2;
    a -= c / 3 * 3;
    b -= c / 3 * 3;
    if (a > b) swap(a, b);
    for (int i = 3; i >= 0; i--) {
        if (i <= a && 2 * i <= b) {
            ans += i;
            break;   
        }
    }
    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;
}

B. Shuffle

按題意模擬便可。url

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/11 22:44:42
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define l first
#define r 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;

void run() {
    int n, m, x;
    cin >> n >> x >> m;
    vector <pii> a(m);
    
    for (int i = 0; i < m; i++) {
        int l, r; cin >> l >> r;
        a[i] = MP(l, r);
    }
    
    int Min = x, Max = x;
    for (int i = 0; i < m; i++) {
        if (min(a[i].r, Max) >= max(a[i].l, Min)) {
            Min = min(a[i].l, Min);
            Max = max(a[i].r, Max);
        }
    }
    cout << Max - Min + 1 << '\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. Palindromic Paths

找出矩陣全部對稱的斜線就行。代碼中有些細節,邊界狀況要注意一下。spa

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/11 22:55:58
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#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;

void run() {
    int n, m; cin >> n >> m;
    vector <vector <int>> a(n, vector <int>(m));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }
    int t = n + m - 1;
    int d = t / 2;
    int ans = 0;
    for (int k = 0; k < d; k++) {
        vector <vector <int>> cnt(2, vector <int>(2));
        int i = 0, j = k;
        if (j >= m) {
            i += j - m + 1;
            j = m - 1;
        }
        while (j >= 0 && i < n) {
            ++cnt[0][a[i][j]];
            ++i, --j;
        }
        i = n - 1, j = m - 1 - k;
        if (j < 0) {
            i += j;
            j = 0;
        }
        while (j < m && i >= 0) {
            ++cnt[1][a[i][j]];
            --i, ++j;
        }
        ans += min(cnt[0][0] + cnt[1][0], cnt[0][1] + cnt[1][1]);
    }
    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;
}

D. Two Divisors

\(a_i=p_1^{q_1}+p_2^{q_2}+\cdots p_k^{q_k}\)構造\(d_1=p_1^{q_1},d_2=\frac{a_i}{d_1}\)就行。
由於有這個式子:
.net

  • \(x,y\)互質,則\(gcd(x+y,xy)=1\)

證實的話視頻裏面有,主要就是用到兩個關於\(gcd\)的性質:code

  • \(gcd(a,b)=gcd(a+b,b)\);
  • \(gcd(a,c)=1\),則\(gcd(a,bc)=gcd(a,b)\)

代碼以下:視頻

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/11 23:23:11
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#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 = 5e5 + 5, M = 2e7 + 5;
 
int n;
 
int cnt;
int p[M];
bool chk[M];
void init() {
    for(int i = 2; i < M; i++) {
        if(!chk[i]) p[++cnt] = i;
        for(int j = 1; j <= cnt && 1ll * i * p[j] < M; j++) {
            chk[i * p[j]] = 1;
            if (i % p[j] == 0) {
                break;
            }
        }
    }
} 
 
pii ans[N];
 
void run() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int x; cin >> x;
        int tmp = x;
        vector <int> v;
        for (int j = 1; j <= cnt; j++) {
            if (1ll * p[j] * p[j] > x) {
                break;
            }
            if (x % p[j] == 0) {
                int t = 1;
                while (x % p[j] == 0) {
                    x /= p[j];
                    t *= p[j];
                }
                v.push_back(t);
            }
        }
        if (x > 1) {
            v.push_back(x);
        }
        if (sz(v) < 2) {
            v = {-1, -1};
        } else {
            v = {v[0], tmp / v[0]};
        }
        ans[i] = MP(v[0], v[1]);
    }
    for (int i = 1; i <= n; i++) {
        cout << ans[i].fi << " \n"[i == n];
    }
    for (int i = 1; i <= n; i++) {
        cout << ans[i].se << " \n"[i == n];
    }
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    init();
    run();
    return 0;
}

E. Two Arrays

首先判掉不合法的狀況,若對於\(a_i=b_k\)且此時\(a_i\)爲最後一次出現,若\(min\{a_{i+1},\cdots,a_n\}<a_i\),那麼就不合法。注意開頭\(a_1,\cdots,a_j,a_j\)\(b_1\)的最後一次出現這段要特判。
以後對於\(1,...,m-1\)每個區間找到儘可能靠左邊的右端點,那麼很容易得知右端點的取值範圍,只要後面的取值合法就行,以後把全部的這些區間乘起來就行。
上述過程能夠二分、單調棧、模擬等多種方法解決。

ip

還有一種比較巧妙的作法,就是維護序列\(a\)的後綴,全部後綴最小值相等的區間自然造成了一段合法的移動區間,咱們對於每一個\(b_i\)把個數乘起來就行。注意一下判斷不合法的狀況,前面說的在實現過程當中乘起來直接等於\(0\),不用特殊判斷;但前面那一段沒法肯定,加上\(suf_1\not ={b_1}\)就行,這裏大了小了都不知足條件。
細節見代碼:
ci

solution1
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/12 9:28:53
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#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, MOD = 998244353;
 
void run() {
    int n, m; cin >> n >> m;
    vector <int> a(n), b(m);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < m; i++) {
        cin >> b[i];
    }
    vector <int> r(m, -1);
    for (int i = n - 1, j = m - 1; i >= 0; i--) {
        if (j >= 0 && a[i] == b[j]) {
            r[j] = i;
            --j;
        }
    }
    if (r[0] == -1) {
        cout << 0 << '\n';
        return;
    }
    r.push_back(n);
    for (int i = 0; i < r[0]; i++) {
        if (a[i] < b[0]) {
            cout << 0 << '\n';
            return;
        }
    }
    for (int j = 0; j < m; j++) {
        for (int i = r[j] + 1; i < r[j + 1]; i++) {
            if (a[i] < b[j]) {
                cout << 0 << '\n';
                return;
            }
        }
    }
    int ans = 1;
    for (int i = 0; i < m - 1; i++) {
        int j = r[i + 1];
        while (j > r[i] && a[j] >= b[i + 1]) {
            --j;
        }
        ans = 1ll * ans * (r[i + 1] - j) % MOD;
    }
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}
solution2
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/12 10:09:52
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#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, MOD = 998244353;
 
void run() {
    int n, m; cin >> n >> m;
    vector <int> a(n), b(m);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < m; i++) {
        cin >> b[i];
    }
    vector <int> suf(n);
    suf[n - 1] = a[n - 1];
    for (int i = n - 2; i >= 0; i--) {
        suf[i] = min(a[i], suf[i + 1]);
    }
    if (suf[0] != b[0]) {
        cout << 0 << '\n';
        return;
    }
    map <int, int> mp;
    for (int i = 0; i < n; i++) {
        ++mp[suf[i]];
    }
    int ans = 1;
    for (int i = 1; i < m; i++) {
        ans = 1ll * ans * mp[b[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;
}
相關文章
相關標籤/搜索