首页 > 其他分享 >Codeforces Round 922 (Div. 2)

Codeforces Round 922 (Div. 2)

时间:2024-02-17 21:22:35浏览次数:28  
标签:int scanf Codeforces while 922 include Div dp dq

A. Brick Wall

因为水平砖块的长度至少为 \(2\),所以一行中水平砖块最多放 \(\lfloor \frac{m}{2} \rfloor\) 块,因此答案不超过 \(n \cdot \lfloor \frac{m}{2} \rfloor\)。如果 \(m\) 是奇数,用长度为 \(\lfloor \frac{m}{2} \rfloor\) 的水平砖块平铺过去,最后一块长度为 \(3\),这样也没有垂直砖块。因此最大稳定性就是 \(n \cdot \lfloor \frac{m}{2} \rfloor\)。

参考代码
#include <cstdio>
int main()
{
    int t; scanf("%d", &t);
    while (t--) {
        int n, m; scanf("%d%d", &n, &m);
        printf("%d\n", m / 2 * n);
    }
    return 0;
}

B. Minimize Inversions

注意对 \(a_i\) 和 \(a_j\)、\(b_i\) 和 \(b_j\) 的操作是同时进行的,不妨假设我们随意调整 \(a\) 的顺序,则原来的每一对 \(a_i\) 和 \(b_i\) 的匹配关系是不变的。令 \(a\) 变得有序,即没有逆序对,这样的状态是逆序对总数最少的状态。

证明:考虑两对元素 \(a_i\) 和 \(a_j\)、\(b_i\) 和 \(b_j \ (i<j)\)。这样数对中每一对的逆序对数可能为 \(0\) 或 \(1\),所以对于两个数对而言,逆序对数可能为 \(0\) 或 \(1\) 或 \(2\)。如果操作前是 \(0\) 对逆序对,那么操作后会变成 \(2\) 对;如果本来是 \(1\) 对,操作后还是 \(1\) 对;如果操作前是 \(2\) 对,操作后是 \(0\) 对。如果将 \(a\) 排成有序,则每一对下标 \(i\) 和 \(j\) 对应的两个数对最多产生 \(1\) 个逆序对,这时不可能通过交换操作将逆序对数再减少了,所以这就是逆序对数量最少的情况。

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

参考代码
#include <cstdio>
const int N = 200005;
int idx[N], b[N];
int main()
{
    int t; scanf("%d", &t);
    while (t--) {
        int n; scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            int x; scanf("%d", &x); idx[x] = i;
        }
        for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
        for (int i = 1; i <= n; i++) printf("%d%c", i, i == n ? '\n' : ' ');
        for (int i = 1; i <= n; i++) printf("%d%c", b[idx[i]], i == n ? '\n' : ' ');
    }
    return 0;
}

C. XOR-distance

考虑 \(a,b,x\) 的二进制表示。分析 \(a\) 和 \(b\) 中同一个位置上的两个二进制位,如果是相等的,则无论 \(x\) 在这一位上取什么值,\(|(a⊕x)−(b⊕x)|\) 在这一位上的贡献必然为 \(0\)。因此 \(x\) 在这一位上应该选 \(0\),因为我们希望 \(x \le r\),所以既然取值无所谓,则应尽量节省。

不妨设 \(a > b\),则存在第一个(最高)位,那一位上 \(a\) 对应的值为 \(1\),\(b\) 对应的值为 \(0\),考虑对于除了这一位以外的之后每一个这样的位,在 \(x\) 的这一位还有机会取 \(1\) 时(即这一位置 \(1\) 后仍小于等于 \(r\))令其取 \(1\),这样一来 \(a \oplus x\) 在这一位上会变成 \(0\),而 \(b \oplus x\) 在这一位上会变成 \(1\),这样能够使得 \(|(a⊕x)−(b⊕x)|\) 的差值尽可能小。

参考代码
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int LOG = 60;
int main()
{
    int t; scanf("%d", &t);
    while (t--) {
        LL a, b, r, x = 0; scanf("%lld%lld%lld", &a, &b, &r);
        if (a < b) swap(a, b);
        bool high = true;
        for (int i = LOG - 1; i >= 0; i--) {
            int ai = (a >> i) & 1, bi = (b >> i) & 1;
            if (ai == 1 && bi == 0) {
                if (!high && r >= 1ll << i) {
                    x += 1ll << i; r -= 1ll << i;
                }
                high = false;
            }
        }
        printf("%lld\n", abs((a ^ x) - (b ^ x)));
    }
    return 0;
}

D. Blocking Elements

考虑二分答案。因为尝试的分隔代价限定得越小,就越难实现,限定得越大则越有可能实现,满足单调性。

当尝试的分隔代价限定为 \(x\) 时,设 \(dp_i\) 表示前 \(i\) 个数,以第 \(i\) 个数作为分隔元素时,在保证每一段的元素和不超过 \(x\) 的情况下,所有的分隔元素之和的最小值,于是 \(dp_i = \min \{ dp_j \} + a_i\),其中 \(j\) 是每一个保证 \([j+1,i-1]\) 的区间和不超过 \(m\) 的位置。由于 \(a_j\) 保证非负,这样的 \(j\) 的取值范围一定是一个连续区间,也就是一个滑动窗口,这个窗口会随着 \(i\) 的右移而右移。因此,这个 \(dp\) 的计算过程可以用单调队列来优化。

时间复杂度为 \(O(n \log \sum a_i)\)。

参考代码
#include <cstdio>
#include <deque>
using namespace std;
typedef long long LL;
const int N = 100005;
int a[N], n;
LL dp[N], sum[N];
bool check(LL x) {
    deque<int> dq; dq.push_back(0);
    int idx = 0; 
    for (int i = 1; i <= n + 1; i++) {
        while (idx <= i && sum[i - 1] - sum[idx] > x) idx++;
        while (!dq.empty() && dq.front() < idx) dq.pop_front();
        dp[i] = dp[dq.front()] + a[i];
        while (!dq.empty() && dp[dq.back()] >= dp[i]) dq.pop_back();
        dq.push_back(i);
    }
    return dp[n + 1] <= x;
}
int main()
{
    int t; scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]); sum[i] = sum[i - 1] + a[i];
        }
        a[n + 1] = 0; sum[n + 1] = sum[n];
        LL ans, l = 1, r = sum[n];
        while (l <= r) {
            LL mid = (l + r) / 2;
            if (check(mid)) {
                r = mid - 1; ans = mid;
            } else l = mid + 1;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

标签:int,scanf,Codeforces,while,922,include,Div,dp,dq
From: https://www.cnblogs.com/ronchen/p/18018433

相关文章

  • Codeforces 解题报告(202402)
    CodeforcesRound926D-SashaandaWalkintheCitydp,主要难点在于设状态。发现子树内一旦存在一个点,到当前子树的根节点路径上有两个危险点,那么除了那条链所属的子树,其他的点就都不能选了。所以把这个性质放进状态,设\(f_{u,0/1}\)表示以\(u\)为根的子树内,是否存在一......
  • Codeforces(1500板刷)
    目录写在前面1.A.DidWeGetEverythingCovered?(构造、思维)题目链接题意题解代码总结2F.Greetings(离散化+树状数组)题目链接题意题解代码总结写在前面开始板刷1500了,主要是最近卡1300-1400上不去,发现cf很多思维题要不是想不到,要不就是签的慢,被读题卡了心态就巨难受,一下就......
  • Codeforces Round 926 (Div. 2) 总结
    A题意:给出一个数组,让你重新排序,\(\sum_{i=1}^{n-1}a_i-a_{i+1}\)最大。做法:显然从小到大排序即可,答案就是最大值减去最小值。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=1e6+5,MOD=998244353;signedmain(){ios::sync_with_s......
  • Codeforces Round 926 (Div. 2) DEF
    D.SashaandaWalkintheCity题意:给定一棵树,问不存在三个点属于同一条路径的点集个数。\(f[x]\)表示,最近公共祖先为\(x\)的合法非空集数量。如果选\(x\),那么只能为不选子树或选一棵子树,否则\(u\insubtree[y_1]\),\(v\insubtree[y_2]\)与\(x\)共链。?贡献为\(......
  • Codeforces Round 926 (Div. 2) 赛后总结
    这场比赛掉了前三场比赛上的分,望周知。SashaandtheBeautifulArray题目大意:一个有n个数的数组,对n个数进行排序,求数组中ai-ai-1(下标从2到n)的和的最大值。分析列出来和式,为an-an-1+an-1-an-2……-a1最后得到an-a1那么an最大,a1最小即可。很容易想到排序。#include<i......
  • Codeforces Round 926 (Div. 2)(A~D)
    目录ABCDA输出最大值减最小值,或者排序算一下答案#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#definepiipair<int,int>#definelllonglong#definedb......
  • Codeforces Round 926 (Div. 2) 题解
    比赛链接:https://codeforces.com/contest/1929官解链接:https://codeforces.com/blog/entry/125943出的很差的一场。推歌CF1929A.SashaandtheBeautifulArray题意任意排列数组\(a_{1..n}\),求\(\sum_{i=2}^n(a_i-a_{i-1})\)的最大值。题解见过最显然的A题,奠定了......
  • Codeforces Round 926 (Div. 2)
    A-SashaandtheBeautifulArray给出的是差分的和,显然等于最后一个减掉第一个,于是答案为最大值减最小值。SubmissionB-SashaandtheDrawing观察到:前几次操作可以使答案\(+2\),之后每次只能让答案\(+1\)。手玩一下发现最优方案是先填满第一列,再从最后一列第二行填到倒......
  • Codeforces Round 906 (Div. 2)
    A.Doremy'sPaint3对于式子\(b_1+b_2=b_2+b_3=\dots=b_{n-1}+b_n=k\),从中挑出\(b_i+b_{i+1}=b_{i+1}+b_{i+2}\),得到\(b_i=b_{i+2}\),这就意味着所有奇数位置上的数需要相等,所有偶数位置上的数也需要相等。对于\(n\)个数而言,有\(\lceil\frac{n}{2}\rc......
  • 数组元素关系映射——cf_925_D. Divisible Pairs
    目录问题概述思路分析参考代码做题反思问题概述原题参考:D.DivisiblePairs给出整数n、x、y和长度为n的数组,要求求出数组中满足以下关系的数对x|ai+ajy|ai-aji<j思路分析刚开始看到这个题的时候觉得没思路,坐牢卡半天发现感觉是对的(裂开)。题解给的是map的做法,看完之......