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

Codeforces Round 922 (Div.2)

时间:2024-01-31 11:24:57浏览次数:31  
标签:arr int ll Codeforces mid Div.2 922 dp dq

题目链接点这里

CF1918A Brick Wall

void solve()
{
    ll n, m;
    cin >> n >> m;
    cout << n * (m / 2) << endl;
}

CF1918B Minimize Inversions

注意到,当其中一个排列有序时,总的逆序对数量最少()

今天找个时间补上证明

对于任意一对 \(i,j\) 位置,其可能的逆序对总贡献度 \(c_{i,j}\) 为 \(0,1,2\) 。由于两个排列对应位置上的元素是绑定的,所以在任意操作后只可能会出现下面几种情况:

  1. 总贡献度 \(c_{i,j}\) 由 \(0\) 变成 \(2\)
  2. 总贡献度 \(c_{i,j}\) 由 \(1\) 变成 \(1\)
  3. 总贡献度 \(c_{i,j}\) 由 \(2\) 变成 \(0\)

那么令其中一个排列有序时,只会出现上面的第 2, 3 种情况(其中一个排列有序时 \(c_{i,j}\) 不会取到 \(2\) )。这样所有的 \(c_{i,j}\) 都取到了最小值,则此时答案最小。

void solve()
{
    int n;
    cin >> n;
    vector<pii> arr(n);
    for (int i = 0; i < n; ++i)
        cin >> arr[i].fi;
    for (int i = 0; i < n; ++i)
        cin >> arr[i].se;
    sort(all(arr));
    for (int i = 0; i < n; ++i)
        cout << arr[i].fi << " ";
    cout << endl;
    for (int i = 0; i < n; ++i)
        cout << arr[i].se << " ";
    cout << endl;
}

CF1918C XOR-distance

为减少讨论,先假设 a > b。

首先将 \(a\),\(b\) 拆位。然后根据异或的性质,当 \(x\) 的某一位取 \(1\) 时,会将原本的 \(0\) 和 \(1\) 翻转,而本题求的是差,所以只要考虑不同的位。于是贪心的从高位到低位考虑,找到第一个不同的位置 \(hdig\),若 \(r\) 可以取这一位为 \(1\),则可以分两种情况考虑:

  1. 翻转该位,则会使 \(a<b\),然后在后面的位置上通过翻转尽量让 \(a\) 贴近 \(b\)。
  2. 不翻转该位,则保留 \(a>b\),然后在后面的位置上通过翻转尽量让 \(b\) 贴近 \(a\)。

若 \(r\) 这一位取不到 \(1\),则只考虑上面的第二种情况。最后取其中的最小值作为答案。

void solve()
{
    ll a, b, r;
    cin >> a >> b >> r;
    if (a == b || r == 0)
    {
        cout << abs(a - b) << endl;
        return;
    }
    if (a <= b)
        swap(a, b);
    int hdig = -1;
    for (int i = 62; i >= 0; --i)
    {
        if (((a >> i) & 1) != ((b >> i) & 1))
        {
            hdig = i;
            break;
        }
    }
    if (r >> hdig)
    {
        ll ans = 4e18;
        // a > b
        ll x = 0;
        for (int i = hdig - 1; i >= 0; --i)
            if (((a >> i) & 1) == 1 && ((b >> i) & 1) == 0)
                if ((x ^ (1ll << i)) <= r)
                    x ^= 1ll << i;
        ans = min(ans, abs((a ^ x) - (b ^ x)));
        // a < b
        x = 1ll << hdig;
        for (int i = hdig - 1; i >= 0; --i)
            if (((a >> i) & 1) == 0 && ((b >> i) & 1) == 1)
                if ((x ^ (1ll << i)) <= r)
                    x ^= 1ll << i;
        ans = min(ans, abs((a ^ x) - (b ^ x)));
        cout << ans << endl;
    }
    else
    {
        // a > b
        ll x = 0;
        for (int i = __lg(r); i >= 0; --i)
            if (((a >> i) & 1) == 1 && ((b >> i) & 1) == 0)
                if ((x ^ (1ll << i)) <= r)
                    x ^= 1ll << i;
        cout << abs((a ^ x) - (b ^ x)) << endl;
    }
}

CF1918D Blocking Elements

这题用到了单调队列优化的 dp 和二分答案。

首先以题目要求的最小花费为 \(mid\) 进行二分。在 \(check\) 函数中,我们优先确保每一段的花费不超过 \(mid\),然后就要考虑如何选择分割点。

在 \(check\) 时直接贪心的选择分割点会 WA,所以我们用 dp 优化选择。定义 \(dp[i]\) 是仅考虑前 \(i\) 个位置,并且以第 \(i\) 个位置作为分割点的分割点花费之和。在求 \(dp\) 值时,先用双指针+前缀和快速确定一个 \(j\) 位置,使得 \(j\) 到 \(i-1\) 这段的花费不大于 \(mid\),即这些位置都是可以向 \(dp[i]\) 转移的位置。然后根据单调队列的性质,队首即是可转移的最小值。最后检查分割点的花费之和是否超过了 \(mid\),即 \(dp[n + 1]\) 是否大于 \(mid\)。

  • dp 转移方程:\(dp[i]=\min \limits_{j \le x \le i-1}(dp[x]) + arr[i]\)
void solve()
{
    int n;
    cin >> n;
    vector<ll> arr(n + 2), pre(n + 2);
    for (int i = 1; i <= n; ++i)
        cin >> arr[i], pre[i] = pre[i - 1] + arr[i];
    ll l = 1, r = 1e14, mid, ans = 1;
    function<bool(ll x)> check = [&](ll x)->bool
    {
        vector<ll> dp(n + 2);
        deque<ll> dq;
        dq.pb(0);
        for (int i = 1, j = 0; i <= n + 1; ++i)
        {
            while (pre[i - 1] - pre[j] > x)
                ++j;
            while (!dq.empty() && dq.front() < j)
                dq.pop_front();
            if (dq.empty())
                return false;
            dp[i] = dp[dq.front()] + arr[i];
            while(!dq.empty() && dp[dq.back()] >= dp[i])
                dq.pop_back();
            dq.pb(i);
        }
        return dp[n + 1] <= x;
    };
    while (l <= r)
    {
        mid = (l + r) / 2;
        if (check(mid))
        {
            ans = mid;
            r = mid - 1;
        }
        else
            l = mid + 1;
    }
    cout << ans << endl;
}

标签:arr,int,ll,Codeforces,mid,Div.2,922,dp,dq
From: https://www.cnblogs.com/tllwtg/p/17998815/2024-01-31-CF_922

相关文章

  • Codeforces Round 922 (Div. 2) A-C
    这次还好,虽然还是不够满意,因为D题没写出来。。A一个明显的贪心,都竖着放就好了#include<bits/stdc++.h>#definelllonglongusingnamespacestd;inlineintread(){ charc=getchar();inta=0,b=1; for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1; for(;c......
  • Codeforces Round 922 (A-C)
    第一次打Div2,对我来说还是很难,写篇博客记录一下~A题题意:T组输入,每组输入一个n,m,代表nm大小的地板,以1k大小的地砖完全覆盖地板(k>=2,且同一地板中k可以不同)。将水平放置的地砖与垂直放置的地砖相减的值定义为稳定性,求最大的稳定性是多少。思路:尽可能的使得水平放置的地砖多,垂......
  • CodeForces 1239E Turtle
    洛谷传送门CF传送门放放/ll/ll/ll。这题是个性质题。首先第一排一定是升序,第二排一定是降序。考虑第一排若存在\(i<j\)使得\(a_{1,i}>a_{1,j}\),那么交换这两个数不会变劣。第二排类似。然后发现在\(1\)走下去或在\(n\)走下去最优。考虑先求出从\(1\)走下去的......
  • Codeforces Round 921 (Div. 2)
    目录写在前面ABCDE写在最后写在前面比赛地址:https://codeforces.com/contest/1925。在床上躺了两天终于复活了妈的。A发现字符串\(s\)合法当且仅当\(s\)可以被分为至少\(n\)段,其中每段都包含\(k\)种字符至少1次。正确性可以归纳证明,这里懒得写了感性理解下。于是......
  • Codeforces Round 921 (Div. 2)
    A-WeGotEverythingCovered!难度:⭐题目大意给定n和k两个整数,要求用前k个小写字母组成一个字符串;该字符串的子串应包含所有由前k个字母组成的长度为n的字符串全排列;要求输出最短的满足条件的字符串;解题思路这题题目挺唬人,但其实是个水题;所谓最短,其实......
  • Codeforces Round 921 (Div. 2)(A~E)
    好久不打用小号水了一场,赛时坑坑拌拌勉强四题,以为美美上分,结果重测时卡掉了我没细想复杂度就交了的B题,这下小丑了 A.WeGotEverythingCovered!直接输出n次连续前k个字母即可#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongsignedmain(){ ios......
  • Codeforces Round 921 (Div. 2)
    CodeforcesRound921(Div.2)A-WeGotEverythingCovered!解题思路:以前\(k\)个字符都出现过至少一次为一轮,构造\(n\)轮即可。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecon......
  • Codeforces Round 920 (Div. 3)
    A-Square难度:⭐题目大意给定正方形的四个顶点,求该正方形的面积;解题思路根据四个点找出长和宽即可,因为数据范围有负数,为了方便我都进行了移位;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false);cin.tie(0......
  • Codeforces Round 921 (Div. 2) A-D
    倒叙讲题预警()传送门:https://codeforces.com/contest/1925D.GoodTrip题意:有n个小盆友,其中m对是好盆友,每队好盆友有友谊度fi。老师要举办k次远足,每次挑一对小盆友去,被挑到的小盆友友谊值+1。如果一对儿童不是朋友,那么他们的友谊值为0,在以后的游览中不会改变。求所有被选中参......
  • Codeforces Round 921 (Div. 1) 记录(A-D)
    比赛链接:https://codeforces.com/contest/1924官解链接:https://codeforces.com/blog/entry/125137这场整体来说表现还可以,最终performance\(2431\),delta\(+33\)。A.DidWeGetEverythingCovered?还不错的贪心题。进入状态有点慢,写了几个小错误B.SpaceHarbourC.Frac......