Codeforces Round #586 (Div. 1 + Div. 2) D. Alex and Julian

link:

https://codeforces.com/contest/1220/problem/D

Meaning of the questions:

Boy Dima gave Julian a birthday present - set B consisting of positive integers. However, he didn't know, that Julian hates sets, but enjoys bipartite graphs more than anything else!

Julian was almost upset, but her friend Alex said, that he can build an undirected graph using this set in such way: let all integer numbers be vertices, then connect any two i and j with an edge if |i−j| belongs to B.

Unfortunately, Julian doesn't like the graph, that was built using B. Alex decided to rectify the situation, so he wants to erase some numbers form B, so that graph built using the new set is bipartite. The difficulty of this task is that the graph, Alex has to work with, has an infinite number of vertices and edges! It is impossible to solve this task alone, so Alex asks you for help. Write a program that erases a subset of minimum size from B so that graph constructed on the new set is bipartite.

Recall, that graph is bipartite if all its vertices can be divided into two disjoint sets such that every edge connects a vertex from different sets.

Ideas:

If a bipartite graph, then there is no strange ring.
Consider the presence of a, there 0-> a, a-> 2a, if present 2a, there 0-> 2a, there is an odd ring, if 4a, 6a also ring there will be odd, as 0-> 4a, 0-> 6a belong to the same side.
consider the presence of p, there 0-> p, there may at the same time, 3p, 5p, p highest power considered in the p 2 multiplied by a after the odd does not increase, the value of p is equal to the power of 2 can exist simultaneously.

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 2e5+10;

LL a[MAXN];
int Cnt[MAXN], Num[100];
int n;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    for (int i = 1;i <= n;i++)
        cin >> a[i];
    for (int i = 1;i <= n;i++)
    {
        LL tmp = a[i];
        while (tmp && tmp%2 == 0)
        {
            Cnt[i]++;
            tmp /= 2;
        }
        Num[Cnt[i]]++;
    }
    int time = 0, id;
    for (int i = 0;i < 64;i++)
        if (Num[i] > time)
            time = Num[i], id = i;
    cout << n-time << endl;
    for (int i = 1;i <= n;i++)
    {
        if (Cnt[i] != id)
            cout << a[i] << ' ' ;
    }
    cout << endl;

    return 0;
}

Guess you like

Origin www.cnblogs.com/YDDDD/p/11626998.html