ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AtCoder Regular Contest 133 题解 A - C

2022-01-23 03:00:26  阅读:184  来源: 互联网

标签:AtCoder int 题解 sum cin 133 leq 减去 inc


本文地址

视频讲解

A - Erase by Value

贪心, 找到第一个出现的相邻逆序.

#include <bits/stdc++.h>
using namespace std;
#define inc(x, l, r) for (int x = l; x <= r; x++)

const int maxn = 1e6 + 5;

int a[maxn];

int main() {
    int n;
    cin >> n;
    inc(i, 1, n) cin >> a[i];
    int x = a[n];
    inc(i, 1, n - 1) {
        if (a[i] > a[i + 1]) {
            x = a[i];
            break;
        }
    }
    vector<int> v;
    inc(i, 1, n) if (a[i] != x) v.push_back(a[i]);
    inc(i, 0, (int)v.size() - 1) cout << v[i] << " \n"[i == (int)v.size() - 1];
}

B - Dividing Subsequence

从左到右扫描 \(p[]\), 如果当前 \(p_i\) 匹配 \(q_j\), 则所有 \(q_k(k < j)\) 不再能与后续 \(p_l(l > i)\) 匹配, 自然想到 dp[p] 为当前 \(p[]\) 只与 \(q_i(i\leq p)\) 的最大匹配值.

\[dp[p] = max(dp[p], \max_{1\leq i\leq p-1}{dp[i]} + 1) \]

为了 \(logn\) 地单点修改和区间查询最大值, 我们可以用线段树或者树状数组. 注意对于 \(p_i\) 更新若干个 \(q_i\) 时要从大到小.

#include <bits/stdc++.h>
using namespace std;
#define inc(x, l, r) for (int x = l; x <= r; x++)
#define lowbit(x) (x & (-x))

const int maxn = 1e6 + 5;

int n, p[maxn], q[maxn], b[maxn];
int pos[maxn];

void update(int i, int val) {
    while (i <= n) {
        b[i] = max(b[i], val);
        i += lowbit(i);
    }
}

int query(int i) {
    int r = 0;
    while (i) {
        r = max(r, b[i]);
        i -= lowbit(i);
    }
    return r;
}

int main() {
    cin >> n;
    inc(i, 1, n) cin >> p[i];
    inc(i, 1, n) {
        cin >> q[i];
        pos[q[i]] = i;
    }
    inc(i, 1, n) {
        vector<int> id;
        inc(j, 1, n / p[i]) id.push_back(pos[p[i] * j]);
        sort(id.begin(), id.end(), greater<int>());
        for (auto e : id)
            update(e, query(e - 1) + 1);
    }
    cout << query(n) << "\n";
}


C - Row Column Sums

显然 \(\sum_{1\leq i\leq h} a[i] \equiv \sum_{1\leq i\leq w} b[i] \pmod k\) 是必要的.

刚开始贪心地给每个格子都填 \(k-1\), 然后算出每一行每一列模 \(k\) 意义下需要减去多少才能满足 \(a[], b[]\) 条件. 设为 \(a[]', b[]'\). 最后只要减去 \(\max(\sum_{1\leq i\leq h} a[i]', \sum_{1\leq i\leq w} b[i]')\) 即可.

描述一下具体减数字的方法. 不妨假设 \(\sum_{1\leq i\leq w} b[i]'\) 更大, 即列的总和. 对于每一列, 我们要减去 \(b[i]'\), 其中 \(b[i]' = (h \times (k - 1) - b[i]) \bmod k\) (行是类似的).

检查当前哪一行还需要减去数字, 就在该行与当前列相交的格子减去1, 如果所有行都不需要再减去数字, 则不妨在第一行与当前列相交的格子减去1. 总共便减去了 \(\sum_{1\leq i\leq w}b[i]'\). 并且除第一行以外的行都不需要再减去数字, 则第一行也满足有关条件(因为行与列减去的数字是一样大的).

#include <bits/stdc++.h>
using namespace std;
#define inc(x, l, r) for (int x = l; x <= r; x++)
#define ll long long

int main() {
    ll h, w, k;
    cin >> h >> w >> k;
    vector<ll> a(h), b(w);
    inc(i, 0, h - 1) cin >> a[i];
    inc(i, 0, w - 1) cin >> b[i];
    if (accumulate(a.begin(), a.end(), 0LL) % k !=
        accumulate(b.begin(), b.end(), 0LL) % k) {
        cout << "-1\n";
        return 0;
    }
    for (ll& e : a)
        e = (k + w * (k - 1) % k - e) % k;
    for (ll& e : b)
        e = (k + h * (k - 1) % k - e) % k;
    cout << h * w * (k - 1) - max(accumulate(a.begin(), a.end(), 0LL),
                                        accumulate(b.begin(), b.end(), 0LL))
         << "\n";
}

标签:AtCoder,int,题解,sum,cin,133,leq,减去,inc
来源: https://www.cnblogs.com/linqi05/p/15835640.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有