2024-08-07 多校联合暑假训练赛第四场 补题+分析

youhualiuh / 2024-08-08 / 原文

A. 小盒子

题意+思路:

题意其实概括的不是非常准确
简要题意:
圆盒有n个格子, 格子自带ai个棋子.是否通过任意起点通过顺时针-1, -2, ... , -n的操作使得
圆盒中所有所有的棋子都为0

思路:
贪心 对于所有棋子通过顺时针操作的时候每一次都是(1 + n) * n / 2次
是一个等差公式所以提前判断所有的值累加起来是否能被除尽,如果不能被
除尽则代表着棋子不能清零.如果可以除尽,总次数是sum / ((1 + n) * n / 2) 次
记录为cnt,那么通过差分得到diff数组,不难得出差分数组是1个di加上n - 1其余
都是减去-1, 那么要让di = 0则需要操作为[(n - 1) * x - (cnt - x) + di == 0]
得到x = (cnt - di) / n及x操作是正整数及cnt - di它是n的倍数, cnt - di也需要>0
那么可以得到一个公式如果当前di - cnt <= 0且保证 (di - cnt) % n == 0
如果所有的di都满足这个条件那么可以清空棋子,否则不可以清空

  

Code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define all(x) (x).begin(), (x).end()
#define debug(x) cout << #x << ' ' << '=' << ' ' << (x) << '\n'
#define debug2(x, y) cout << #x << ' ' << '=' << ' ' << (x) << ',' << ' ' << #y << ' ' << '=' << ' ' << (y) << ' ' << '\n'
mt19937 rng(std::chrono::system_clock::now().time_since_epoch().count());

const int N = 1e5 + 5;
ll a[N], diff[N];

void solve() {
    ll n;
    ll sum = 0;
    cin >> n; 
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum += a[i];
    }
    if (sum % ((1 + n) * n / 2)) {
        cout << "NO";
        exit(0);
    }
    ll cnt = sum / ((1 + n) * n / 2);
    for (int i = 0; i < n; i++) {
        diff[i] = a[(i + 1) % n] - a[i] - cnt;
    }
    for (int i = 0; i < n; i++) {
        if (diff[i] > 0 || diff[i] % n) {
            cout << "NO\n";
            return ;
        } 
    }
    cout << "YES\n";
    return ;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(15);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

  

B. 更多的假期

不会

 

 

C. 新位置

 

 

D. 彩色球

dp+贪心 不过目前只想到n * n * k的朴素写法 不会

 

 

E. 交换一次

 

 

F. 套箱子

不会

 

 

G.选边

树形dp

 

 

H. 替换(本场签到)

题意+思路:

简要题意:
将每次操作将bi 元素 替换为 ci 并且输出每一次操作后元素和
思路:
计数 cnt[i] 代表i有几个 在每次查询更新答案即可
每一次查询[b, c]. 
[ans - cnt[b] * b](代表原先的) + [ans + cnt[b] * c](替换后的)
cnt[c] += cnt[b](将替换后的+原本存在的)
cnt[b] = 0(清空)

  

Code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define all(x) (x).begin(), (x).end()
#define debug(x) cout << #x << ' ' << '=' << ' ' << (x) << '\n'
#define debug2(x, y) cout << #x << ' ' << '=' << ' ' << (x) << ',' << ' ' << #y << ' ' << '=' << ' ' << (y) << ' ' << '\n'
mt19937 rng(std::chrono::system_clock::now().time_since_epoch().count());

const int N = 1e5 + 5;
ll cnt[N];

void solve() {
    int n;
    cin >> n;
    ll ans = 0;
    for (int i = 1, x; i <= n; i++) {
        cin >> x;
        cnt[x]++;
        ans += x * 1ll;
    }
    int q;
    cin >> q;
    while (q--) {
        int b, c;
        cin >> b >> c;
        ans -= cnt[b] * b;
        ans += cnt[b] * c;
        cnt[c] += cnt[b];
        cnt[b] = 0;
        cout << ans << '\n';
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(15);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

  

I. 排位置

不会

 

J. 2019的倍数

 

 

K. 四象之力

dp