B - Bitwise Exclusive-OR Sequence

将每个数二进制表示下的每一位分开考虑,位与位之间不会互相影响,我们对有关系的两个点建图,建好后对每一位根据异或关系染色,(颜色的确定可以根据异或运算的自反性得到 即

A xor B xor B =A)如果染色出现矛盾,就可以确定该异或关系必然不能产生合法序列,直接输出-1即可,在染色种统1的个数,因为是异或操作,所以图中染色的0和1的位置可以互换,

所以我们再统计一个该联通块中点的总数,用总数减去1的个数就可以得到0的个数,其实这里的0和1表示的是图中两类相斥点的数量,你需要贪心的选择在数量较少的那一类填1,以使得序列的和最小。注意对于每一位都有可能出现多个不连通的联通分量,因为每个联通分量合法性相互之间不会影响,所以我们可以取每个联通分量的较小的那一类的数量然后累加。

这个是#define int long long     在超时的边缘

 

 这个是手开long long

 

ACcode

#include <iostream>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<map>
#include<unordered_map>
#define int long long
#define endl '\n'
#define lowbit(x) (x &-x)
#define mh(x) memset(x, -1, sizeof h)
#define debug(x) cerr << #x << "=" << x << endl;
#define brk exit(0);
using namespace std;
void inline TLE() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); }
const int N = 2e5 + 10;
const int M = 2 * N;
const int mod = 998244353;
const double esp = 1e-6;
const double pi = acos(-1);
typedef pair<int, int> PII;
typedef long long LL;

int e[2 * N], w[2 * N], ne[2 * N], h[N], cnt;
int color[31][N];

void add(int a, int b, int c) {
    e[cnt] = b, w[cnt] = c, ne[cnt] = h[a], h[a] = cnt++;
}
int sum = 0;
int dfs(int u, int f, int itcolor)
{
    sum++;
    color[f][u] = itcolor;
    //cout << itcolor << endl;
    int res = itcolor;
    for (int i = h[u];~i;i = ne[i]) {
        int j = e[i];
        if (color[f][j] == -1) {
            res += dfs(j, f, ((w[i] >> f)&1) ^ itcolor);
        }
        else if (color[f][j] != ((w[i] >> f)&1) ^ itcolor) {
            cout << "-1" << endl;
            exit(0);
        }
    }
    return res;
}

signed main()
{
    TLE();
    memset(color, -1, sizeof color);
    memset(h, -1, sizeof h);
    int n, m;
    cin >> n >> m;
    while (m--)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c);
        add(b, a, c);
    }
    int p = 1;
    int  res = 0;
    for (int i = 0;i < 31;i++)
    {
        for (int j = 1;j <= n;j++)
            if (color[i][j] == -1)
            {
                sum = 0;
                int t = dfs(j, i, 1);
                res +=p* min(t, sum - t);
                //cout <<sum<<" " <<t << endl;
            }
        p <<= 1LL;
    }
    cout << res << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值