首页 > 其他分享 >Codeforces Round 960 (Div. 2)(A - D)

Codeforces Round 960 (Div. 2)(A - D)

时间:2024-07-21 17:41:12浏览次数:8  
标签:typedef 960 int ll Codeforces long using Div const

Codeforces Round 960 (Div. 2)(A - D)

A - Submission Bait

解题思路:

假设直接选最大数,如果最大数有奇数个,\(Alice\)必胜,反之必败。

根据这个思路,从大到小看数字,找到第一个出现奇数次的数,从它开始选,就能保证每次\(Alice\)选的时候还剩奇数个选项。

代码:

#include <bits/stdc++.h>
#include <cxxabi.h>
using namespace std;
using ll = long long;
using i128 = __int128_t;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
#define fi first
#define se second
const int N = 2e5 + 10;
const int M = 60;
const ll inf = 1ll << 30;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l, int r) { return rng() % (r - l + 1) + l; }

void solve()
{
    int n;
    cin >> n;
    vector<int> cnt(n + 10);
    for (int i = 1; i <= n; i++)
    {
        int t;
        cin >> t;
        cnt[t]++;
    }
    for (int i = n; i; i--)
    {
        cnt[i] += cnt[i + 1];
        if (cnt[i] & 1)
        {
            cout << "YES\n";
            return;
        }
    }
    cout << "NO\n";
}

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

B - Array Craft

解题思路:

整个序列分为三段\([1, y + 1],[y, x],[x + 1, n]\)。

\([x,y]\)全部填正数,这样只要加上这一段一定比不加要更大。

对于最大前缀和来说,\([x + 1, n]\)区间中\(sum(x + 1,... ,k)\in [x + 1, n]\)一定得小于等于\(0\)。先考虑能否取尽量小?不方便构造,因为如果尽量往小取,我们还要反过来考虑\(suf[y, ...,n] >suf[x - 1, ...n]\)。所以,考虑使得后缀和为零。

如果\(n - (x + 1)\)为偶数,我们按\(-1, 1\)的规律一定能让其最后和为零。

如果\(n - (x + 1)\)是奇数,我们可以最终让区间和为\(-1\)。发现\([x,y]\)区间全部取\(1\)区间和都有\(2\),一定大于\(-1\),满足后缀和条件,所以可以这么构造。

对于区间\([1, y + 1]\)同理考虑。

代码:

#include <bits/stdc++.h>
#include <cxxabi.h>
using namespace std;
using ll = long long;
using i128 = __int128_t;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
#define fi first
#define se second
const int N = 2e5 + 10;
const int M = 60;
const ll inf = 1ll << 30;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l, int r) { return rng() % (r - l + 1) + l; }

void solve()
{
    int n, x, y;
    cin >> n >> x >> y;
    vector<int> a(n + 1);
    int l = 1;
    int r = y - 1;
    int len = r - l + 1;
    if (len & 1)
    {
        int cur = -1;
        for (int i = l; i <= r; i++)
        {
            a[i] = cur;
            cur *= -1;
        }
    }
    else
    {
        int cur = 1;
        for (int i = l; i <= r; i++)
        {
            a[i] = cur;
            cur *= -1;
        }
    }
    for (int i = y; i <= x; i++)
    {
        a[i] = 1;
    }
    l = x + 1;
    r = n;
    int cur = -1;
    for (int i = l; i <= r; i++)
    {
        a[i] = cur;
        cur *= -1;
    }
    for (int i = 1; i <= n; i++)
    {
        cout << a[i] << " \n"[i == n];
    }
}

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

C - Mad MAD Sum

解题思路:

举例\((1,1,1,2,2,2)\rightarrow (0,1,1,1,2,2) \rightarrow (0,0,1,1,1,2) \rightarrow (0,0,0,1,1,1)\)。

像这样玩一下,不难发现,变化后的序列一定是一个单调递增的序列,且每一段相同数字的变化都是有迹可循的。

比如,最大数段会不断变短,前面数段会不断右移。

考虑到初始序列不具备这样的性质,所以可以先对原序列进行两次操作,然后对第二次操作后的单调序列按照上述性质模拟即可。

两次操作后,出了最大数段,不可能出现数段长度为\(1\)的情况。这个情况处理起来麻烦且会出现在前两次操作中,所以直接操作掉即可。

代码:

#include <bits/stdc++.h>
#include <cxxabi.h>
using namespace std;
using ll = long long;
using i128 = __int128_t;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
#define fi first
#define se second
const int N = 2e5 + 10;
const int M = 60;
const ll inf = 1ll << 30;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l, int r) { return rng() % (r - l + 1) + l; }

void solve()
{
    ll n;
    cin >> n;
    ll ans = 0;
    vector<ll> a(n + 1), pos(n + 1), cnt(n + 1);
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        a[i] = x;
        ans += x;
    }
    ll mx = 0;
    for (int i = 1; i <= n; i++)
    {
        cnt[a[i]]++;
        if (cnt[a[i]] == 2)
        {
            pos[a[i]] = i;
        }
        if (a[i] > mx && cnt[a[i]] >= 2)
        {
            mx = a[i];
        }
        a[i] = mx;
        ans += a[i];
        // cout << i << ' ' << a[i] << endl;
    }
    for (int i = 1; i <= n; i++)
    {
        cnt[i] = pos[i] = 0;
    }
    for (int i = 1; i <= n; i++)
    {
        cnt[a[i]]++;
        if (cnt[a[i]] == 2)
        {
            pos[a[i]] = i;
        }
    }
    ll r = n;
    for (ll i = n; i; i--)
    {
        if (cnt[i] < 2 || pos[i] > r)
        {
            continue;
        }
        ll m = r - pos[i] + 1;
        ans += (m * (m + 1)) / 2 * i;
        if (r != n && m > 1)
        {
            ans += (n - 1 - r + 1) * m * i;
        }
        r = pos[i] - 1;
    }
    cout << ans << '\n';
}

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

D - Grid Puzzle

解题思路:

操作次数上限为\(n\),就是一行一行地变白。尝试用\(2 \times 2\)涂白优化。

举例:

  • \((1, 1),(1, 2),(2, 1),(2, 2)\):都可以一次涂白两行,操作数为一。由此也可见,这里\(1\)和\(2\)其实是等价的,少的那个\(1\)并无优化空间。
  • \((2, 4, 4, 4,4, 2)\):这种两端\(2\)中间连续的\(4\),操作数都可以优化到行数减一。同理,把中间连续的\(4\)部分换成\(3\)也行,\(3,4\)在这里也是等价的。
  • 这样我们就还可以把\((2, 2)\)这种看作中间连续的\(4\)数量为\(0\)的情况。

枚举下标,只有当前\(a_i = 2\)时,我们可以尝试优化操作数。其中\((1, 2)\)等价\((3, 4)\)等价。其余操作,都是直接将当前行涂白最优。

注意:手画一下就能发现,中间\(4\)的个数一定得是偶数个才能尝试优化。

代码:

#include <bits/stdc++.h>
#include <cxxabi.h>
using namespace std;
using ll = long long;
using i128 = __int128_t;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
#define fi first
#define se second
const int N = 2e5 + 10;
const int M = 60;
const ll inf = 1ll << 30;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l, int r) { return rng() % (r - l + 1) + l; }

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1), dp(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        // 等价
        if (a[i] == 1)
        {
            a[i] = 2;
        }
        // 等价
        if (a[i] == 3)
        {
            a[i] = 4;
        }
    }
    int len = 0;
    for (int i = 1; i <= n; i++)
    {
        dp[i] = dp[i - 1] + (a[i] == 0 ? 0 : 1);
        // 只有2结尾有可能优化操作次数
        if (a[i] == 2 && a[i - len - 1] == 2 && len % 2 == 0)
        {
            dp[i] = min(dp[i], dp[i - len - 2] + len + 1);
        }
        if (a[i] == 4)
        {
            len++;
        }
        else
        {
            len = 0;
        }
    }
    cout << dp[n] << endl;
}

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

标签:typedef,960,int,ll,Codeforces,long,using,Div,const
From: https://www.cnblogs.com/value0/p/18314731

相关文章

  • Codeforces Round 960 (Div. 2)
    Preface周日开始补之前欠下的CF博客,这周一共有三场就按照从后往前的顺序补吧这场经典前期唐完了,前4题上来每题WA一发也是神人了,最后做到E的时候只有50min了结果还把题看错了以为树的形态都是不确定的,怀疑人生了好久感觉这个题完全没法做,后面看了眼样例才发现树的形态......
  • Codeforces Round 960(Div.2)
    CodeforcesRound960(Div.2)A从大到小去判断数字个数的奇偶性,只要出现过奇数,先手必赢,如果不出现奇数,后手必赢#include<iostream>#include<queue>#include<map>#include<set>usingnamespacestd;constintN=55;inta[N];voidsolve(){ intn; cin>>n; ma......
  • 题解:Codeforces Round 960 (Div. 2) D
    D.GridPuzzletimelimitpertest:2secondsmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputYouaregivenanarray\(a\)ofsize\(n\).Thereisan\(n\timesn\)grid.Inthe\(i\)-throw,thefirst\(a_i\)......
  • 题解:Codeforces Round 960 (Div. 2) C
    C.MadMADSumtimelimitpertest:2secondsmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputWedefinethe\(\operatorname{MAD}\)(MaximumAppearingDuplicate)inanarrayasthelargestnumberthatappearsatleast......
  • Codeforces
    Round959A给定\(n*m\)数组\(a\),$1\lea_i\len*m$并且两两不同,问是否存在数组\(b\),也使用这些元素,并且每个位置的值都与\(a\)不同。\(1*1\)数组特判,其他循环移位。B给定01串s和t,可以对s任意次执行以下操作:选择l,r,将l,r异或等长前缀,问s和t是否能相等对于s和t第一个......
  • Codeforces Round 960 (Div. 2) A - D
    link好图好图qwq这次也是终于装上插件codeforcesbetter!了,妈妈再也不用担心我的英语啦A-SubmissionBaitA先手,B后手,优先往奇偶性的方向想一开始我只是单纯考虑A总是选最大值的数的奇偶性,样例过了?交上去发现wa2然后恼...瞎搞了个33344,发现A可以先选3......
  • 题解:Codeforces Round 960 (Div. 2) B
    B.ArrayCrafttimelimitpertest:1secondmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputForanarray\(b\)ofsize\(m\),wedefine:themaximumprefixpositionof\(b\)isthesmallestindex\(i\)thatsat......
  • Codeforces Round 960 (Div.2) 补题
    A非常容易观察到性质,注意Alice为先手,发现当\(a_{\max}\)的个数为奇数时显然能win,但如果\(a_{\max}\)的个数为偶数且有一个数具有奇数个可以作为跳板,那么也能win,否则就lose。B结论:\(presum_x\geq2+presum_{y-1}\geq2+\min{presum_i}\geq1+\max{presum_i}......
  • 题解:Codeforces Round 960 (Div. 2) A
    A.SubmissionBaittimelimitpertest:1secondmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputAliceandBobareplayingagameinanarray\(a\)ofsize\(n\).Theytaketurnstodooperations,withAlicestarting......
  • Codeforces Round 960 (Div. 2) 补题记录(A~D)
    打的稀烂,但是还是上分了(A考虑对值域做一个后缀和。若某一个后缀和的值是奇数那么先手就可以获胜。否则就不可以获胜。(我才不会告诉你我这题吃了一次罚时的)#pragmaGCCoptimize(3)#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;intmysqrt(intx){......