首页 > 其他分享 >2024-2025 ICPC, NERC, Southern and Volga Russian Regional Contest B. Make It Equal

2024-2025 ICPC, NERC, Southern and Volga Russian Regional Contest B. Make It Equal

时间:2024-11-20 23:18:02浏览次数:1  
标签:log Contest int 题解 Make Regional Equal 操作

因为和题解有所区别,所以写一发题解增长见识。

题面

B. Make It Equal

给你一个大小为 \(n\) 的整数数组 \(a\) 。数组元素的编号从 \(1\) 到 \(n\) 。

您可以执行以下任意次数的操作(可能为 0 次):从 \(1\) 到 \(n\) 中选择一个索引 \(i\) ;将 \(a_i\) 减少 \(2\) ,并将 \(a_{(i \bmod n) + 1}\) 增加 \(1\) 。

执行这些操作后,数组中的所有元素都应是非负等整数

你的任务是计算最少需要执行的操作次数。

题解

考虑将 \(a_i\) 写作二进制形式,从第 \(0\) 位开始计数(方便描述)。

如果第 \(j(j > 0)\) 位为 \(1\),\(a_i\) 可以自减 \(2^j\),操作次数为 \(2^{j-1}\),同时对 \(1 \le t < j\) 的每个 \(a_{i + t}\) 做 \(2^{j - t - 1}\) 次操作,可以发现,只有 \(a_{i+j}\) 的值增加了 \(1\)。

循环操作之后,可以发现所有的 \(a_i\) 是小于等于 \(1\) 的,如果所有的 \(a_i\) 不都等于 \(1\),那么答案不存在,考虑退回一次操作需要让 \(a_i \ge 2\),让所有的 \(a_i \ge 1\) 后容易发现对所有位置做一次操作后回到了 \(a_i \le 1\),且恰好为原来位置的取反值,因此只有全 \(0\) 和全 \(1\) 有解。

对于最小的解只需要所有操作数减去最小操作数即可。

第一次循环操作复杂度是 \(O(n\log^2{a_i})\),第二次循环操作是 \(O(n)\) 的。

对赋值的操作精细化可以去掉第一次循环的 \(O(\log{a_i})\),用 \(\operatorname{lowbit}\) 优化直接去计算需要减去的值可以去掉对位的枚举做到 \(O(n)\)。

时间复杂度 \(O(n\log^2{a_i})\) 的代码如下,\(O(n)\) 应该不难实现。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve()
{
    int n;
    cin >> n;
    vector<ll> a(n), cnt(n);
    for (int i = 0; i < n; i ++ ) cin >> a[i];
    int pd = 0;
    while (!pd)
    {
        pd = 1;
        for (int i = 0; i < n; i ++ )
        {
            if (a[i] <= 1) continue;
            pd = 0;
            int t = 1;
            while (1ll << (t + 1) <= a[i]) t ++ ;
            for (int j = t; j; j -- )
            {
                if (a[i] >> j & 1)
                {
                    a[i] ^= 1ll << j;
                    a[(i + j) % n] ++ ;
                    for (int k = 0; k < j; k ++ ) cnt[(i + k) % n] += 1ll << (j - k - 1);
                }
            }
        }
    }
    int num = count(a.begin(), a.end(), 1);
    if (num != n) cout << "-1\n";
    else
    {
        ll minn = *min_element(cnt.begin(), cnt.end());
        ll res = accumulate(cnt.begin(), cnt.end(), 0) - n * minn;
        cout << res << "\n";
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int T = 1;
    cin >> T;
    while (T -- ) solve();
    return 0;
}

标签:log,Contest,int,题解,Make,Regional,Equal,操作
From: https://www.cnblogs.com/YipChipqwq/p/18559613

相关文章

  • Atcoder Regular Contest 059 题解
    ARC059C.BeTogether签到题。枚举要改成哪个,因为值域只有\([-100,100]\)。然后对总代价取个\(\min\)即可。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constLLMAXN=105;LLn,A[MAXN];intmain(){ ios::sync_with_stdio(false); cin.ti......
  • Atcoder Regular Contest 058 题解
    ARC058C.Iroha'sObsession*1174\(n\)再大一点的就是巨大恶心分类讨论。但我们注意到\(n\leq10^4\),所以我们可以直接暴力枚举然后写个check。首先我们先把被ban掉的数存标记一下。然后从\(n\)开始往上查,一直查到\(10^6\)基本就可以了。然后每次检查一下有没有数位被......
  • AtCoder Beginner Contest 380
    AtCoderBeginnerContest380总结A用桶统计\(1\),\(2\),\(3\)出现的次数,判断即可。#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include......
  • AtCoder Beginner Contest 352 - VP记录
    A-AtCoderLine赛时整活想写异或版本的swap写错了还WA了一发。不过现在会写了:x^=y^=x^=y点击查看代码#include<cstdio>#include<algorithm>usingnamespacestd;intmain(){ intn,x,y,z; scanf("%d%d%d%d",&n,&x,&y,&z); if(x>y)swap(x,y); p......
  • The 2024 ICPC Asia East Continent Online Contest (II) K.Match
    题面K.Match给定长度为\(n\)的两个序列\(a\)和\(b\),当且仅当\(a_i\oplusb_j\gek\)时,\(a_i\)与\(b_j\)连一条双向边,其中\(\oplus\)表示XOR运算。对于\([1,n]\)范围内的每个\(x\),计算大小为\(x\)的匹配数的个数,结果对\(998244353\)取模。题解考虑两......
  • Atcoder Beginner Contest 367
    老规矩此处略过前三题,不过B值得关注一下。D题 Pedometer思路肥肠煎蛋,只需要搞一个前缀额然后看前面的前缀和是否有跟当前的前缀和同余的情况(%M)暴力求解这步是O(n^2)的,因此需要优化。这里就用到了一个技巧——哈希表消除分支。所谓的哈希表消除分支其实就是mp[pre_s]存一......
  • 题解:CF contest 2037 : [Codeforces Round 988 (Div. 3)] (A-E)
    ATwice题面Kinich醒来迎接新的一天的开始。他打开手机,查看邮箱,发现了一份神秘的礼物。他决定打开礼物的盒子。Kinich用\(n\)整数打开数组\(a\)。最初,Kinich的分数是\(0\)。他将执行任意次数的以下操作:—选择两个索引\(i\)和\(j\)\((1\leqi\lt;j\leqn)\),确......
  • AtCoder Beginner Contest 380 (A~E)题解
    A-123233遍历字符串统计出现次数即可。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e6+10;intn,m,k;inta[N];signedmain(){ strings; cin>>s; map<char,int>mp; for(autot:s){ mp[t]++; } if(......
  • [题解]AtCoder Beginner Contest 380(ABC380) A~F
    A-123233照题意统计即可。点击查看代码#include<bits/stdc++.h>usingnamespacestd;strings;map<char,int>ma;signedmain(){ cin>>s; for(chari:s)ma[i]++; if(ma['1']==1&&ma['2']==2&&ma['3']==3)co......
  • 【未完结】 AtCoder Beginner Contest 380 题解
    AtCoderBeginnerContest380Rated:\(770\)A-123233简单模拟B-HurdleParsing字符串模拟C-MoveSegment找到第\(k\)个块的下标,模拟。D-StrangeMirroringE-1DBucketToolF-ExchangeGameG-AnotherShuffleWindow......