zoukankan      html  css  js  c++  java
  • Codeforces

    题意:

      n张卡牌,正反两面有两个数字。每一面的概率都为0.5。将所有卡片的值异或起来,求异或值不为0的概率。

    题解:

      考虑异或值为0的情况。

      用sum表示a[1]^...^a[n]的值。用c[i]表示a[i]^b[i]。那么sum^c[i]^...^c[j]代表总的异或值。即sum=c[i]^...^c[j]时,他们的异或值为0。

      那么问题就变成求c的子集,使得子集内的所有值异或和为sum。

      求出c[1]~c[n]的线性基,用bit数组表示。

      对于sum,若他不能用线性基表示,即总的异或和恒不为0,答案就为1/1。

      如果能用线性基表示,所有异或和为sum的情况数就为2n-tot(tot为线性基的大小)。异或和为0的概率为2n-tot/2n = 1/2tot

      那么异或和不为0的概率为(2tot-1)/2tot

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 5e5+10;
    int n;
    int tot;
    ll b, sum;
    ll a, bit[65];
    void add(ll *a, ll b) {
        for(int i = 62; i >= 0; i--) if((1ll<<i)&b) {
            if(a[i]) b ^= a[i];
            else {
                a[i] = b; 
                tot++;
                return ;
            }
        }
    }
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%lld%lld", &a, &b);
            sum ^= a;
            add(bit, a^b);
        }
        int cnt;
        for(int i = 62; i >= 0; i--) if((1ll<<i)&sum) {
            sum ^= bit[i];
            cnt++;
        }
        if(sum) {
            puts("1/1");
            return 0;
        }
        ll ans = 1ll<<tot;
        printf("%lld/%lld
    ", ans-1, ans);
    } 
    View Code
  • 相关阅读:
    RedHat的定制安装
    Linux系统概述
    嵌入式学习方法
    mysql联合查询
    mysql之count
    memcached安装
    css书写规则
    nginx的fastcgi_param参数详解
    array_2.array_rand
    array_1.array_map
  • 原文地址:https://www.cnblogs.com/Pneuis/p/9090955.html
Copyright © 2011-2022 走看看