• CodeTON Round 3 (Div. 1 + Div. 2, Rated, Prizes!) A-D


    比赛链接

    A

    题解

    知识点:贪心。

    注意到 \(a[1] \neq 1\)\(1\) 永远不可能换到前面;\(a[1] = 1\) 可以交换后面任意元素。

    时间复杂度 \(O(n)\)

    空间复杂度 \(O(n)\)

    代码

    #include
    #define ll long long
    using namespace std;
    int a[20];
    bool solve() {
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) cin >> a[i];
    if (a[1] == 1) cout << "YES" << '\n';
    else cout << "NO" << '\n';
    return true;
    }
    int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
    if (!solve()) cout << -1 << '\n';
    }
    return 0;
    }

    B

    题解

    知识点:贪心,枚举。

    分两类,一种是纯 \(1\)\(0\) ,另一种是杂合。

    显然后者的情况中,把所有数字全选了是最优的;前者枚举一下所有纯子串即可。两种情况,取最大值。

    时间复杂度 \(O(n)\)

    空间复杂度 \(O(n)\)

    代码

    #include
    #define ll long long
    using namespace std;
    bool solve() {
    int n;
    cin >> n;
    string s;
    cin >> s;
    s = "?" + s;
    int cnt0 = 0, cnt1 = 0;
    for (int i = 1;i <= n;i++) {
    if (s[i] == '0') cnt0++;
    else cnt1++;
    }
    ll mx = 1LL * cnt0 * cnt1;
    int i = 1, j = 1;
    while (i <= n) {
    while (j <= n && s[j] == s[i]) j++;
    mx = max(mx, 1LL * (j - i) * (j - i));
    i = j;
    }
    cout << mx << '\n';
    return true;
    }
    int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
    if (!solve()) cout << -1 << '\n';
    }
    return 0;
    }

    C

    题解

    知识点:构造。

    注意到,只有 \(a=b\) 或者 \(a\) 每位都不等于 \(b\) 的对应位才可行。

    考虑先把 \(a\) 串的 \(1\) 一个一个消掉,然后发现 \(b\) 会出现全 \(0\)\(1\) 的情况,接下来分类讨论:

    1. 如果 \(a = b\) ,那么 \(a\)\(1\) 为偶数时得到的 \(b\)\(0\) ,否则是 \(1\)
    2. 如果 \(a\) 每位都不等于 \(b\) 的对应位 ,那么消掉一个 \(1\) 以后又会回到情况1,因此和情况 \(1\) 相反。

    全是 \(0\) 直接可以结束,全是 \(1\) 可以先把 \([1,n]\) 取反,然后选择 \([1,1],[2,n]\) 即可。

    时间复杂度 \(O(n)\)

    空间复杂度 \(O(n)\)

    代码

    #include
    #define ll long long
    using namespace std;
    bool solve() {
    int n;
    cin >> n;
    string a, b;
    cin >> a >> b;
    a = "?" + a;
    b = "?" + b;
    int cnt = 0;
    for (int i = 1;i <= n;i++) cnt += a[i] == b[i];
    if (cnt != 0 && cnt != n) return 0;
    bool flag = cnt == n ? 0 : 1;
    vector<pair<int, int>> ans;
    for (int i = 1;i <= n;i++) {
    if (a[i] == '1') {
    ans.push_back({ i, i });
    flag ^= 1;
    }
    }
    if (flag) {
    ans.push_back({ 1,n });
    ans.push_back({ 1,1 });
    ans.push_back({ 2,n });
    }
    cout << "YES" << '\n';
    cout << ans.size() << '\n';
    for (auto [i, j] : ans) cout << i << ' ' << j << '\n';
    return true;
    }
    int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
    if (!solve()) cout << "NO" << '\n';
    }
    return 0;
    }

    D

    题解

    知识点:分解质因数,容斥原理,数论。

    题目要求我们每个 \(b_i\) 的方案数,然后得到总的方案数。

    显然有 \(gcd(a_{i-1},b_i) = a_i\) ,注意到 \(a_i\) 必须是 \(a_{i-1}\) 的因子否则不可能得到答案,因此特判一下 \(a_{i} | a_{i-1}\)

    于是,我们要找到所有的 \(b_i\) ,满足 \(gcd(\frac{a_{i-1}}{a_i},\frac{b_i}{a_i}) = 1\)\(a_i | b_i\) ,其中 \(\frac{b_i}{a_i} \in [1,\frac{m}{a_i}]\) ,即我们从 \([1,\frac{m}{a_i}]\) 整数中找到和 \(\frac{a_{i-1}}{a_i}\) 互素的个数。

    这是一个典型的容斥问题。先对 \(\frac{a_{i-1}}{a_i}\) 分解素因数,得到其素因子种类。我们先计算出区间中包含 \(\frac{a_{i-1}}{a_i}\) 因子的数的个数,注意奇加偶减,然后用总数 \(\frac{m}{a_i}\) 减去个数,即与之互素的数的个数,于是我们就得到了 \(b_i\) 的种类。

    遍历每个 \(a_i\) 即可。

    时间复杂度 \(O(n(\log a_i + 10\cdot 2^{10}))\)

    代码

    #include
    #define ll long long
    using namespace std;
    const int mod = 998244353;
    int a[200007];
    bool vis[100007];
    int prime[100007];
    int cnt;
    void euler_screen(int n) {
    for (int i = 2;i <= n;i++) {
    if (!vis[i]) prime[++cnt] = i;
    for (int j = 1;j <= cnt && i * prime[j] <= n;j++) {
    vis[i * prime[j]] = 1;
    if (!(i % prime[j])) break;//如果到了i的最小质因子就不用继续,因为接下去的数x一定能被(i,x)之间的数筛掉
    }
    }
    }///欧拉筛,O(n),每个合数只会被最小质因子筛掉
    bool solve() {
    int n, m;
    cin >> n >> m;
    for (int i = 1;i <= n;i++) cin >> a[i];
    int ans = 1;
    for (int i = 2;i <= n;i++) {
    if (a[i - 1] % a[i]) {
    ans = 0;
    break;
    }
    int d = a[i - 1] / a[i];//不能出现的因子
    int base = m / a[i];//包含a[i]的数个数
    vector<int> ft;//对d分解因子种类
    for (int j = 1;j <= cnt && prime[j] <= d / prime[j];j++) {
    if (d % prime[j] == 0) ft.push_back(prime[j]);
    while (d % prime[j] == 0) d /= prime[j];
    }
    if (d > 1) ft.push_back(d);
    int sum = 0;//容斥原理,求[1,base]中没有d中因子的数个数
    for (int j = 1; j < (1 << ft.size()); j++) {
    int mul = 1, feat = 0;
    for (int k = 0; k < ft.size(); k++) {
    if (j & (1 << k)) {
    mul *= ft[k];
    feat++;
    }
    }
    if (feat & 1) sum = (sum + 1LL * base / mul % mod) % mod;
    else sum = (sum - 1LL * base / mul % mod + mod) % mod;
    }
    sum = (base - sum + mod) % mod;
    ans = 1LL * ans * sum % mod;
    }
    cout << ans << '\n';
    return true;
    }
    int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    euler_screen(100007);
    while (t--) {
    if (!solve()) cout << -1 << '\n';
    }
    return 0;
    }
  • 相关阅读:
    python基于PHP+MySQL的网上书店网上图书销售系统
    医疗行业:容灾备份平台建设及运维难点
    Redis配置文件
    C++智能指针
    面向“三创”人才培养的计算机类专业课程体系与教学内容改革研究
    【毕业季】走一步看一步?一个自动化er对大学四年的思考
    Go语法的特殊之处
    【Prometheus】k8s集群部署node-exporter
    php利用ZipArchive类实现文件压缩与解压
    MySQL多表查询——子查询(临时表,all、any操作符)
  • 原文地址:https://www.cnblogs.com/BlankYang/p/16867434.html