Codeforces Round #726 (Div. 2)

Codeforces Round #726 (Div. 2)

A - Arithmetic Array

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n; m = -n;
        rep (i, 1, n) cin >> k, m += k;
        cout << (m >= 0 ? m : 1) << '\n';
    }
    return 0;
}

B - Bad Boy

int main() {
    IOS;
    for (cin >> _; _; --_) {
        int x, y; cin >> n >> m >> x >> y;
        cout << "1 1 " << n << ' ' << m << '\n';
    }
    return 0;
}

C - Challenging Cliffs

int a[N];
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n;
        rep (i, 1, n) cin >> a[i];
        sort(a + 1, a + 1 + n);
        int mi = 2e9, k = 0;
        rep (i, 1, n - 1) if (umin(mi, a[i + 1] - a[i])) k = i;
        cout << a[k];
        rep (i, k + 2, n) cout << ' ' << a[i];
        rep (i, 1, k - 1) cout << ' ' << a[i];
        cout << ' ' << a[k + 1] << '\n';
    }
    return 0;
}

D - Deleting Divisors

  1. 对于一个不是2的幂次的偶数,则必定存在其他的奇因子,存在方法使得当前n变成奇数

  2. 对于一个奇数,要么已经是质数了,必败态,否则无论怎么减,都会变成不是2的次幂的偶数,而对手可以通过1,让当前玩家再次回到奇数,故此为必败态

  3. 对于是2的幂的数,那只跟2的次方有关,奇数必败(根2,一样,一方可以控制是的使得对方回合永远是2的奇次幂)

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n;
        if ((n & 1) || n == 2) cout << "Bob\n";
        else {
            for (m = 0; !(n & 1); ++m, n >>= 1);
            if (n == 1) cout << (m & 1 ? "Bob" : "Alice") << '\n';
            else cout << "Alice\n";
        }
    }
    return 0;
}

E - Erase and Extend

注意到只有当\(s_i<s_1\) 的时候循环序列会变长

\(s_i>s_1\) 直接break,无论如何都不可能比当前循环序列更优

最麻烦的是\(s_i=s_1\) 又要比较 \(s_{i+1},s_{1+1}\) 直到两者不相等,暴力超时

所以我们要与处理出来两个位置第一次不同的位置的下标,直接KMP完事

记得要复制一倍,因为比较的时候会越界

char s[N];
int f[N];
 
void kmp(char *s) {
    f[1] = strlen(s + 1);
    for (int i = 2, l = 0, r = 1; i <= f[1]; ++i) {
        if (i <= r) f[i] = min(r - i + 1, f[i - l + 1]);
        while (i + f[i] <= f[1] && s[i + f[i]] == s[1 + f[i]]) ++f[i];
        if (i + f[i] - 1 > r) r = f[i] + i - 1, l = i;
    }
}
 
int main() {
    IOS; cin >> n >> k >> s + 1;
    rep (i, 1, n) s[i + n] = s[i];
    m = n <<= 1; kmp(s);
    rep (i, 2, n >> 1)
        if (i + f[i] <= n && s[i + f[i]] > s[f[i] + 1]) { m = i - 1; break; }
    //cout << m;
    rep (i, 1, k) cout << s[(i - 1) % m + 1];
    return 0;
}

F - Figure Fixing

首先, 注意到不论怎么变,奇偶性不会变,每次改变两个点,点的权值的奇偶性不变,若权值和目标奇偶性不同无解

若当前图为二分图,则白点一共改变多少,黑点也改变多少,则白黑点集权值和目标差相同

不为二分图,则至少存在两一对可以同时加,也可以一个加一个减,打破了白黑点集权值和目标差相同,肯定能成功

ll a[N], b[N], c[N];
VI h[N];

bool dfs(int x) {
    for (auto &y : h[x])
        if (c[y] == c[x]) return false;
        else if (!c[y]) {
            c[y] = 1 ^ c[x];
            if (!dfs(y)) return false;
        }
    return true;
}

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> m;
        rep (i, 1, n) cin >> a[i], c[i] = 0, clear(h[i]);
        rep (i, 1, n) cin >> b[i]; c[1] = 2;
        rep (i, 1, m) {
            int u, v; cin >> u >> v;
            h[u].pb(v); h[v].pb(u);
        }
        if (dfs(1)) {
            ll s[2] = {0, 0};
            rep (i, 1, n) s[c[i] - 2] += a[i] - b[i];
            cout << (s[0] == s[1] ? "YES" : "NO") << '\n';
        } else {
            bool s[2] = {0, 0};
            rep (i, 1, n) s[0] ^= a[i] & 1, s[1] ^= b[i] & 1;
            cout << (s[0] == s[1] ? "YES" : "NO") << '\n';
        }
    }
    return 0;
}
posted @ 2021-06-22 17:17  洛绫璃  阅读(81)  评论(0编辑  收藏  举报