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

Codeforces Round 897 (Div. 2) A-E

时间:2023-09-18 12:35:28浏览次数:38  
标签:le 长为 897 int pos Codeforces cnt1 Div oplus

A. green_gold_dog, array and permutation

题意:给出一个长为\(n\)的数组\(a\),找到一个长为\(n\)的排列\(b\),使得\(a\)与\(b\)对应位置上的元素的差尽可能大

Solution

将数组\(a\)排序,然后令排列\(n,n-1,...,2,1\)对应到对应的元素即可

struct node
{
    int x, id;
    bool operator<(const node &t) const &
    {
        return x < t.x;
    }
}e[N];
int b[N];
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> e[i].x;
        e[i].id = i;
    }
    sort(e+1,e+1+n);
    for(int i=1;i<=n;i++)
    {
    	b[e[i].id]=n-i+1;
    }
    for(int i=1;i<=n;i++)
    {
    	cout<<b[i]<<" \n"[i==n];
    }
}

B. XOR Palindromes

题意:给出一个长为\(n\)的01串\(s\),定义实数\(x\)为\(good\),有以下条件

存在一个长为\(n\)的含有\(x\)个1的01串\(l\),在把\(s_i\)替换成\(s_i \oplus l_i\)后,\(s\)变成回文串

对于每一个\(0\le t\le n\),如果存在\(good\)实数,输出1,反之输出0

Solution

假设\(s\)在对称位置有\(cnt1\)个不同对数,\(cnt2\)个相同对数,则至少需要\(cnt1\)个1才能使得\(s\)变为回文

然后我们考虑\(n\)的奇偶性

对于偶数的情况,我们发现,从\(cnt1\)出发,每次必须选择一对相同对数,才能维护\(s\)的回文状态,一直到\(cnt1+2cnt2\)为止,并且对于中间的第\(x\)个,如果\((x-cnt1)\)是奇数,则不合法,反之合法

对于奇数数的情况,则是到\(cnt1+2cnt2+1\)为止,并且对于中间所有的都是合法的

然后把已经是回文的情况特判一下即可

void solve()
{
    int n;
    cin >> n;
    for (int i = 0; i <= n; i++)
        vis[i] = 0;
    string s;
    cin >> s;
    int cnt2 = 0, cnt1 = 0;
    for (int i = 0; i < n / 2; i++)
    {
        if (s[i] != s[n - i - 1])
            cnt1++;
        else
            cnt2++;
    }
 
    string t = s;
    reverse(t.begin(), t.end());
    if (t == s)
    {
        if (n % 2 == 0)
        {
            for (int i = 0; i <= n; i++)
            {
                if (i & 1)
                    cout << "0";
                else
                    cout << "1";
            }
        }
        else
        {
            for (int i = 0; i <= n; i++)
                cout << "1";
        }
        cout << "\n";
        return;
    }
    cout << "0";
    for (int i = 1; i <= n; i++)
    {
        if (i < cnt1)
            cout << "0";
        else
        {
            if (n & 1)
            {
                if (i - cnt1 <= 2 * cnt2 + 1)
                    cout << "1";
                else
                    cout << "0";
            }
            else if (i - cnt1 <= 2 * cnt2 && (i - cnt1) % 2 == 0)
                cout << "1";
            else
                cout << "0";
        }
    }
 
    cout << "\n";
    //cout << cnt1 << " " << cnt2 << "\n";
}

C. Salyg1n and the MEX Game

题意:给出一个集合\(S\),Alice先手,Alice每次可以加入一个数\(x(0\le x\le 1e9)\),Bob每次可以删除一个\(y(0\le y\le 1e9)\),其中\(y<x\),如果不能删除,则返回-1,进行若干次使得MEX(S)最大。

Solution

假设从0开始最高的是到\(n\),那么我们可以加入\(n+1\),则Bob必须删除一个小于它的数,然后我们可以把那个数加回来,这样就能使得MEX(S)最大

void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    int pos = -1;
    for (int i = 1; i <= n; i++)
    {
        if (a[i] == pos + 1)
        {
            pos++;
        }
    }
    pos++;
    int y;
    cout << pos << endl;
    cin >> y;
    while (y != -1)
    {
        pos = y;
        cout << pos << endl;
        cin >> y;
    }
}

D. Cyclic Operations

题意:有一个数组\(a\),一开始全0,现在可以进行下面操作无数次

选择一个长为\(k\)的数组\(l\)(对于\(1\le i \le n\),都有\(1\le l_i \le n\),且它们是完全不同的),然后令\(a_{l_i}\)变为\(l_{(i\%k)+1}\)

现在给出一个数组\(b\),问\(a\)能否经过若干次操作变为\(b\)

Solution

考虑到每次操作其实是生成了一个长为k的环,而在已经在环上数进行操作,则其实是将其拆开并再生成一个环,所以我们可以把它变成一个图,直接bfs,然后看每个点能否到达一个长为k的环,这样就可以判断了

void solve()
{
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        vis[i] = 0;
        b[i] = 0;
    }
    if (k == 1)
    {
        for (int i = 1; i <= n; i++)
        {
            if (a[i] != i)
            {
                cout << "NO\n";
                return;
            }
        }
        cout << "YES\n";
        return;
    }
    else
    {
        for (int i = 1; i <= n; i++)
        {
            if (vis[i])
                continue;
            int pos = i;
            int idx = 1;
            int flag = 0; //flag感觉好像没啥用(
            set<int> v;
            while (!vis[pos])
            {
                v.insert(pos);
                vis[pos] = 1;
                b[pos] = idx;
                pos = a[pos];
                idx++;
            }
            if (v.count(pos))
            {
 
                int x = idx - b[pos];
                if (x != k)
                {
                    cout << "NO\n";
                    return;
                }
                flag = 1;
            }
            else
            {
                flag = 1;
            }
            if (!flag)
            {
                /*for (int i = 1; i <= n; i++)
                    cout << b[i] << " \n"[i == n];*/
                cout << "NO\n";
                return;
            }
        }
        /* for (int i = 1; i <= n; i++)
                     cout << b[i] << " \n"[i == n];*/
        cout << "YES\n";
    }
}

E. Salyg1n and Array

题意:有一个数组\(a\),长为\(n\),给出一个数字\(k\),\(n,k\)均为偶数,且有\(1\le k \le n \le k^2 \le 2500\),现在每次询问\(i\)可以得到\(a_i \oplus a_{i+1} \oplus...\oplus a_{i+k-1}\),询问后,询问的部分会反转,求\(a_1 \oplus a_{2} \oplus...\oplus a_{n}\)

Solution

我们先经过若干次操作直接询问,可以得到\(a_1\oplus a_{2} \oplus...\oplus a_{mk}\)

剩下\(k+x\)个,每次询问后都会反转

假设询问的重叠部分长为\(a\),未重叠的则为\(b\),\(c\)表示一共进行了这么多次操作,则有

\[\begin{cases} a+b=k\\ a+bc=k+x \end{cases} \]

其中\(c\)必须是奇数,这样我们就可以得到剩余部分的异或和

枚举\(a\)即可,最多操作次数为51次

void solve()
{
    int n, k;
    cin >> n >> k;
    if (n % k == 0)
    {
        int ans = 0;
        for (int i = 1; i <= n / k; i++)
        {
            cout << "? " << (i - 1) * k + 1 << endl;
            int x;
            cin >> x;
            ans ^= x;
        }
        cout << "! " << ans << endl;
    }
    else
    {
        int ans = 0;
        for (int i = 1; i <= n / k - 1; i++)
        {
            cout << "? " << (i - 1) * k + 1 << endl;
            int x;
            cin >> x;
            //x = 1;
            ans ^= x;
        }
 
        int res = n - (n / k - 1) * k;
        int st = (n / k - 1) * k;
 
        for (int i = 1; i < k; i++)
        {
            int x = i, y = k - i;
            if ((res - i) % y == 0)
            {
                int z = (res - i) / y;
                if (z & 1)
                {
                   // cout << z << endl;
                    
                    for (int i = 1; i <= z; i++)
                    {
                        cout << "? " << st + (i - 1) * y + 1 << endl;
                        int xx;
                        cin >> xx;
                        //xx = 1;
                        ans ^= xx;
                    }
                    cout << "! " << ans << endl;
                    return;
                }
            }
        }
    }
}

标签:le,长为,897,int,pos,Codeforces,cnt1,Div,oplus
From: https://www.cnblogs.com/HikariFears/p/17711571.html

相关文章

  • css让某个view/div 定在某一个位置不动
    position:absolute 可以定位在某个位置,但是会跟着滚动条的位置而改变。postion:fixed可以定位在某个位置,并且也不会跟着滚动条的位置而改变。 postion:fixedleft:0px;bottom:0px; 会定位在底部左边位置。比如返回顶部/返回等。......
  • CodeForces 1863G Swaps
    洛谷传送门CF传送门看到\(a_{a_i}\)和\(a_i\in[1,n]\),果断连边\(i\toa_i\),得到内向基环森林。那么每次相当于把\(a_i\)变成自环,连边\(i\toa_{a_i}\)。但是每次操作都改变图的形态很不好办,考虑打标记。每次\(\operatorname{swap}(a_i,a_{a_i})\),我们就把\(i......
  • div 让a内容居中方法
    <div>标签是HTML中的一个重要标签,它代表了一个文档中的一个分割区块或一个部分。在<div>标签中,我们可以放置各种内容,包括文本、图像、链接等等。有时候,我们需要将其中的链接<a>标签的内容水平居中显示,这就需要使用CSS设置div内部链接的居中显示。本文将详细讲解如何使用CSS使得<di......
  • Codeforces Global Round 17 A. Anti Light's Cell Guessing
    给一个\(n\timesm\)的网格,里面藏了一个炸弹\((x_0,y_0)\)。你可以选择\(k\)个坐标\((x_1,y_1),(x_2,y_2),\cdots,(x_k,y_k)\)。第\(i\)次选择计算机会回复你一个数\(d_i=|x_0-x_i|+|y_0-y_i|\)。至少需要选出多少个坐标才能确定\((x_0,y_0)\)的位......
  • Deltix Round, Autumn 2021 (open for everyone, rated, Div. 1 + Div. 2) A. Divide
    有一个长为\(n\)的数组,可以执行以下整份操作任意次:选择任意两个数\(a_i,a_j\),满足\(2\mida_i\)\(a_i=\frac{a_i}{2}\)\(a_j=2\cdota_j\)请找到经过任意此操作后的最大\(\sum_{i=1}^{n}a_i\)。在唯一分解定理下讨论两个数\(a_i=2^{\alpha_i}\cdotx,a......
  • 如何使用透明的div实现页面背景模糊效果
    要在页面背景上实现模糊效果,并使内容区域(<div>)保持半透明,你可以使用CSS的backdrop-filter属性。这个属性可以用于设置页面背景的滤镜效果,而不影响内部内容的模糊。下面是一个示例的代码片段,展示如何实现这个效果:<!DOCTYPEhtml><html><head><title>背景模糊效果</title>......
  • Codeforces Round 764 (Div. 3) B. Make AP
    有三个正整数\(a,b,c\)。需要执行以下操作严格一次:选择任意一个正整数\(m\)并让严格一个\(a,b,c\)之一乘以\(m\)。但不能改变他们的顺序。回答是否可以经过一次操作后使\(a,b,c\)变为等差。分类讨论题:三种情况满足一种即可。(已知\(a,b,c\geq1\))\(ma......
  • Codeforces Round 773 (Div. 2) B. Power Walking
    有\(n\)个增幅道具,第\(i\)个道具种类为\(a_i\),一个人的强度\(w\)为他所有道具的种类数。对于\(k]\in[1,n]\),询问将\(n\)个道具分配给\(k\)个人且每个人至少分配到一个道具后,能够得到的最想强度和\(\sum_{i=1}^{n}w_i\)。观察一:最低强度和\(\sum_{i=1}^{k}w......
  • Educational Codeforces Round 100
    B.FindTheArray对于条件二来说,1是万金油的存在,所以我们只需要把奇数位置或偶数位置全部变成1即可。因为要求差值小于\(\fracs2\),所以我可以求出奇偶位的和修改较小值即可。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongusingpii=pair<in......
  • codeforces图论合集
    CyclicOperations给定一个数组$a$,每次构造一个数组$\spacel\space$长度为$\spacek\space$,数组$\spacea\space$与$\spacel\space$转换关系如下:$a_{l_1}\tol_2\space,\spacea_{l_2}\tol_3\space,\spacea_{l_3}\tol_4\space,\space...\space,\spacea_{l_n}\tol_1$......