ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #819 (Div. 1 + Div. 2) and Grimoire of Code Annual Contest 2022

2022-09-10 00:01:52  阅读:198  来源: 互联网

标签:Code 题意 Contest int vis fa 序列 Div


Codeforces Round #819 (Div. 1 + Div. 2) and Grimoire of Code Annual Contest 2022

A:Mainak and Array 思维

题意:

给定一串序列,你可以进行如下操作

 

 

 询问经过多次操作后,得到的(an-a1)的最大值。

思路:

情况1:如果选择整个区间,我们只能选择相对下标差为n-1的两个数

情况2:不改变a1,在其他数中选出最大值作an

情况3:不改变an,在其他数中选出最小值作a1

 

B: Mainak and Interesting Sequence 构造

 题意:

给定序列元素个数n,以及元素总和m,我们需要构造出一个序列满足所有小于ai的数异或和为0(ai为正数)

思路:

首先n>m一定无法构造。然后异或和为0,代表着小于ai的aj一定有偶数个,因为aj^aj=0。为了方便,我们首先用1填充,如果n%1=1,最后在1序列末尾加上一个m-(n-1)即可;如果n%2=0,最后需要加上的2个(m-(n-2))/2,但如果(m-(n-2))%1==1,我们也无法构造,因为这样始终会有两个数无法凑成一对

 

C. Jatayu's Balanced Bracket Sequence 思维

 题意:给定一个合法括号序列(当“()”内部合法,这个括号才是合法的),根据这个合法序列建图,询问有多少个联通分量

样例:

3 ()(())

 

 思路:

真的建图去跑感觉上也行,但属实是下下策。我们可以发现“)(”这样的序列并没有使图出现新的连通块,但“((”会使连通块数量+1,所以遍历整个序列就行,但注意最开始整体本就是一个连通块,所以最后答案要+1

void solve() {
    cin >> n;
    int inx = 0, cnt = 0, ans = 0, ans2 = 0, ans3 = 0;
    for (int i = 1; i <= 2 * n; i++)
        cin>> line[i];
    for (int i = 1; i <= 2 * n - 1; i++) {
        if (line[i] == '(' && line[i + 1] == '(')
            ans++;
        if (line[i] == '(' && line[i + 1] == ')')
            ans2++;
        if (line[i] == ')' && line[i + 1] == '(')
            ans3++;
    }
    cout << ans2+ans-ans3 << endl;
    return;
}
int

 

D. Edge Split(联通图)

题意:

给出一个有n个点,m条边的无向图,我们对所有的边黑白染色,定义只有黑边存在时的连通块个数为c1,相对的只用白边存在时联通块的个数为c2,求c1+c2有最小值所有边的染色情况(m>=n-1&&m<=n+2)

思路:

首先我们可以明确,加入一条边后连通块数量会-1(不形成环),所以最优策略一定是没有环的;其次因为是求总和,所以无论怎么分配每种颜色对最后的结果都没影响。所以我们首先对整个图跑生成树并将这些边染为白色,然后如果剩下的边没有形成环便可直接得出;如果有环我们需要将其中任意一条边染为白色来去掉这个环,但如此以来白色中就出现了环,所以我们还需要将被改色的边的顶点的另一条边染为黑色。

#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 2e5 + 10;
int fa[MAX_N], t, n, m;
int find(int x)
{
    if (fa[x] != x)
        fa[x] = find(fa[x]);
    return fa[x];
}
struct node
{
    int u, v, id;
}e[MAX_N];
bool vis[MAX_N];
void work()
{
    vector<node> v1, v2;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) fa[i] = i;
    set<int> s;
    for (int i = 1; i <= m; i++)
    {
        int u, v;
        cin >> u >> v;
        e[i] = { u,v,i };
        int x = find(u), y = find(v);
        if (x != y)
        {
            vis[i] = 1;
            fa[x] = y;
            v1.push_back(e[i]);
        }
        else
        {
            s.insert(e[i].v);
            s.insert(e[i].u);
            vis[i] = 0;
            v2.push_back(e[i]);
        }
    }
    if (m == n + 2 && s.size() == 3)
    {
        node e2 = v2.back();
        vis[e2.id] = 1;
        for (auto e1 : v1)
        {
            if (e1.u == e2.u || e1.v == e2.u)
                vis[e1.id] = 0;
        }
    }
    for (int i = 1; i <= m; i++)cout << vis[i];
    cout << endl;
}
int main() {
    std::ios::sync_with_stdio(false);//加快cin读取速度的
    cin.tie(0);
    cout.tie(0);
    cin >> t;
    while (t--) {
        work();
    }

}

 

标签:Code,题意,Contest,int,vis,fa,序列,Div
来源: https://www.cnblogs.com/Aacaod/p/16675769.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有