首页 > 其他分享 >Codeforces Round 832 (Div2)

Codeforces Round 832 (Div2)

时间:2023-04-16 23:33:51浏览次数:44  
标签:832 const cout 奇数 int Codeforces Alice 区间 Div2

Swap Game

Alice 和 Bob 两个人在玩游戏。

有一个长度为 \(n\) 的序列 \(a\),Alice 和 Bob 两人轮流完成一个操作,Alice 先开始。

每个人可以将数列的第一个数减 \(1\),并将它与后面序列的一个数进行交换,如果一个人操作之前发现当前序列中的第一个数为 \(0\),这个人就输了。

问如果两人都足够聪明,最后谁会赢?

题解:

我们发现必败态是\(a_1=0\),我们考虑由于两个人都会选择最优的策略,也就是说每个人一定会挑\([2,n]\)中最小的数和\(a_1\)交换,因为这样能使得对方快速遇到\(a_1=0\),所以说必败态为\(a_1\)是最小值

  1. 如果一开始\(a_1\)本身就是最小值,也就是说Alice开局就是必败态,那么他无论如何都走不到一个必败态,也就是说Bob始终能留给Alice必败态的局面,所以Alice必败
  2. 如果一开始\(a_1\)不是最小值,那么Alice每次都能抛给bob必败态,所以Alice必胜
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10;

int n;

void solve()
{
    cin >> n;
    int res = 0;
    int a;
    cin >> a;
    bool flag = false;
    for (int i = 2; i <= n; ++i)
    {
        int x;
        cin >> x;
        if (x < a)
        {
            flag = true;
        }
    }
    if (flag)
        cout << "Alice" << endl;
    else
        cout << "Bob" << endl;
}
signed main(void)
{
    Zeoy;
    int T = 1;
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

Yet Another Problem

给定长度为\(n\)序列\(a\),存在\(q\)次询问,每次询问给定区间\([l,r]\),现在支持这样的操作:选定一段奇数长度的区间\(l\leq L\leq R\leq r\),可以使得这段区间的所有元素变成\(a_L\bigoplus a_{L+1}...\bigoplus a_R\),对于每次询问回答至少需要多少次操作才能使得区间\([l,r]\)中的所有元素都变成0,如果无法成功输出\(-1\)

\(1\leq a_i \leq 2^{30}\)

题解:二进制 + 思维 + 二分 + 离散化

我们发现如果区间\([l,r]\)的异或和不为0,一定不可能成功,因为每次选定的是奇数长度的区间

如果区间\([l,r]\)异或和为0,那么存在以下几种情况:

  1. 如果区间\([l,r]\)中所有元素本来全部为0,最小操作次数为0;
  2. 如果区间\([l,r]\)的长度为奇数,最小操作次数为1;
  3. 如果区间\([l,r]\)的长度为偶数:
  4. 如果\(a[l]=0\) 或者 \(a[r] = 0\),最少操作次数为1;
  5. 如果该区间存在奇数长度的区间\([l,i]\)异或和为0,那么最小操作次数为2;
  6. 不满足上面情况的都无法成功

再来讲一下如何快速得知是否存在奇数长度的区间\([l,i]\)异或和为0,我们可以邻接表维护每一个前缀异或和的奇数位置和偶数位置,如果\(l\)为奇数我们就在相同前缀异或和中找到大于\(l\)的第一个奇数位置,如果\(l\)是偶数位置同理;但是我们发现\(a_i\)太大了,所以我们需要利用哈希表离散化(映射)

#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 1e6 + 10, M = 4e5 + 10;

int n, q;
int a[N];
int pre[N];
int sum[N];
unordered_map<int, vector<int>> mp1, mp2;

void solve()
{
    cin >> n >> q;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    for (int i = 1; i <= n; ++i)
    {
        sum[i] = sum[i - 1] + (a[i] == 0);
        pre[i] = pre[i - 1] ^ a[i];
    }
    for (int i = 1; i <= n; ++i)
    {
        if (i % 2 == 1)
            mp1[pre[i]].push_back(i);
        else
            mp2[pre[i]].push_back(i);
    }
    while (q--)
    {
        int l, r;
        cin >> l >> r;
        if (pre[r] != pre[l - 1])
        {
            cout << -1 << endl;
            continue;
        }
        if (sum[r] - sum[l - 1] == r - l + 1)
        {
            cout << 0 << endl;
            continue;
        }
        if ((r - l + 1) % 2 == 1)
        {
            cout << 1 << endl;
            continue;
        }
        if (a[l] == 0 || a[r] == 0)
        {
            cout << 1 << endl;
            continue;
        }
        int x = pre[l - 1];
        if (l % 2 == 1)
        {
            int p = lower_bound(all(mp1[x]), l) - mp1[x].begin();
            if (p == mp1[x].end() - mp1[x].begin() || mp1[x][p] > r)
            {
                cout << -1 << endl;
                continue;
            }
            cout << 2 << endl;
        }
        else
        {
            int p = lower_bound(all(mp2[x]), l) - mp2[x].begin();
            if (p == mp2[x].end() - mp2[x].begin() || mp2[x][p] > r)
            {
                cout << -1 << endl;
                continue;
            }
            cout << 2 << endl;
        }
    }
}
signed main(void)
{
    Zeoy;
    int T = 1;
    // cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

标签:832,const,cout,奇数,int,Codeforces,Alice,区间,Div2
From: https://www.cnblogs.com/Zeoy-kkk/p/17324423.html

相关文章

  • Codeforces Round 764 (Div. 3) -- E. Masha-forgetful
    **题目大意:取去模板串中的子串可以组成一个给定的目标串,每个子串可以用无数次,输出组成的所需的串的信息题目中的取得子串必须“>=2”很好的提示了我们,想到一个式子2*x+3*y可以等于任何数,所以从之前的串都取长度为2,为3。在进行匹配。**structnode{ intl,......
  • Codeforces Round 856 (Div2)
    CountingFactorizations任何一个正整数\(m\)都可以被唯一的分解为\(p_1^{e_1}\cdotp_2^{e_2}\ldotsp_k^{e_k}\)的形式。将正整数\(m\)的唯一质数分解转化为一个长度为\(2k\)的可重集合记为\(f(m)\)。\[f(m)=\{p_1,e_1,p_2,e_2,p_3,e_3,\ldots,p_k,e_k\}\]......
  • Codeforces Round 866 (Div. 2) A~C
     这场,非常快落!是难得对中国选手友好的时间(17:05) A观察一下,发现在连续的___中插入^就好,然后特判一下首尾,发现很像小学奥数的那个植树问题哇(注意特判一下只有一个^#include<bits/stdc++.h>usingnamespacestd;voidsolve(){strings;cin>>s;intn=s.len......
  • Codeforces Round 628 (Div. 2) A-D
    CodeforcesRound628(Div.2)A.EhAbAnDgCdvoidsolve(){intn=read();for(inti=1;i*i<=n;i++){intg=__gcd(i,n-i);if(g*g+i*(n-i)==n*g){cout<<i<<""<<n-i<<endl;bre......
  • Codeforces Round 862 (Div. 2)
    Preface补题ing这场思路挺顺的,早上上课的时候口胡了前5题下午都一发写过了然后想了30min的F1也Rush出来了,不过F2还是有点仙的做不动A.WeNeedtheZeroSB题,首先判断是否所有数的异或和等于\(0\)若不为\(0\)且\(n\)为偶数则无解,否则答案就是这个异或和本身#include<cstdio......
  • [Educational Codeforces Round 118 (Rated for Div. 2)]题解
    A题意:给定两个数,每一个数有两个属性,第一个属性是p1,第二个属性是p2.表示这个数有p2个后缀0.这个数本身等于p1后面加p2个0.问给你两个这种数,判断大小。思路:赛场上想到的:如果最终的长度不一样,可以直接根据长度判断。如果相等,就把后缀0加上直接比较大小就可以(比较字典序的大小),但......
  • Educational Codeforces Round 110 (Rated for Div. 2) C. Unstable String(状态机)
    https://codeforces.com/contest/1535/problem/C题目大意:给定一个字符串s,由10?组成:?每次都可以任意替换成0或者1问我们这个子字符串中,能够组成010101这样两两互不相等的字符串的数量最大是多少?input30?10????10??1100output8625#include<bits/stdc++.h>usin......
  • Educational Codeforces Round 120 (Rated for Div. 2)
    题目链接C核心思路这是一个很好的二分的题目,首先我们判断题目可不可二分,很显然是可以的把。因为假设我们x是可以的话,x+1...肯定也是可以的,但是x-1,x-2....这些又是不可以的。好,接下来思考二分刚开始的左右边界,左边届很好想,关键是右边界。这个其实也不难。因为我们最坏肯定是全......
  • Codeforces Round #289 Div. 2 解题报告 A.B.C.E
    A-MaximuminTable纯递推。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib.h>#include<map>#include<set>#include<stdio.h>usingn......
  • Codeforces Round #290 (Div. 2) 解题报告 A.B.C.D.
    A-FoxAndSnake模拟。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib.h>#include<map>#include<set>#include<stdio.h>usingnames......