• bzoj 2337: [HNOI2011]XOR和路径


    论直接存储无向边会发生什么……

    感觉已经不会高斯肖元了呢QAQ

    按位考虑,

    令(f_x)表示(x)到(n)、xor值为(1)的期望

    那么对于不是汇点的(x)有(f_x = frac{sum f_{in_x} (1 - 2val)+val} {deg_{in_x}})

    #include <bits/stdc++.h>
    #define N 110
    #define M 20000
    #define eps 1e-10
    #define LF long double
    using namespace std;
    LF ans;
    int n, m;
    int ai[M], bi[M], ci[M];
    LF mat[N][N];
    int s;
    int out[N];
    void put()
    {
        for (int i = 1; i <= s; ++ i)
        {
            for (int j = 1; j <= s + 1; ++ j)
                printf("%.3lf ", mat[i][j]);
            puts("");
        }
    }
    void G()
    {
        //put();
        for (int i = 1; i <= s; ++ i)
            for (int j = i + 1; j <= s; ++ j)
                if (abs(mat[i][i]) < eps)
                    for (int k = i; k <= s + 1; ++ k) swap(mat[j][k], mat[i][k]);
                else 
                    for (int k = s + 1; k >= i; -- k)
                        mat[j][k] -= mat[j][i] / mat[i][i] * mat[i][k];
        for (int i = s; i; -- i)
        {
            LF d = mat[i][s + 1];
            for (int j = i + 1; j <= s; ++ j)
                d -= mat[j][s + 1] * mat[i][j];
            mat[i][s + 1] = d / mat[i][i];
        }
        //put();
    }
    int main()
    {
        scanf("%d%d", &n, &m); s = n;
        for (int i = 1; i <= m; ++ i)
        {
            scanf("%d%d%d", &ai[i], &bi[i], &ci[i]);
            out[ai[i]] ++; if (bi[i] != ai[i]) out[bi[i]] ++;
        }
        for (int p = 0; p <= 30; ++ p)
        {
            memset(mat, 0, sizeof mat);
            for (int i = 1; i <= n; ++ i)
                mat[i][i] = 1;
            for (int i = 1; i <= m; ++ i) if (ai[i] != n)
                if (ci[i] & (1 << p))
                    mat[ai[i]][bi[i]] += 1.0 / out[ai[i]],
                    mat[ai[i]][n + 1] += 1.0 / out[ai[i]];
                else 
                    mat[ai[i]][bi[i]] -= 1.0 / out[ai[i]];
            for (int i = 1; i <= m; ++ i) if (bi[i] != n && ai[i] != bi[i])
                if (ci[i] & (1 << p))
                    mat[bi[i]][ai[i]] += 1.0 / out[bi[i]],
                    mat[bi[i]][n + 1] += 1.0 / out[bi[i]];
                else 
                    mat[bi[i]][ai[i]] -= 1.0 / out[bi[i]];
            //printf("%d : 
    ", p);
            G();
            ans += (mat[1][n + 1]) * (1 << p);
        }
        printf("%.3lf", (double)ans);
    }
  • 相关阅读:
    Fiddler实现手机抓包——小白入门
    linux中的baff/cache占用大量内存,如何清理?
    禁止用su切换到root
    Cookie和Session和token
    HTTP 与HTTPS
    Tcp/Ip的分层
    IP基础知识
    计算机基础<一>
    【java基础】内部类
    【JAVA基础】Java中四种权限修饰符
  • 原文地址:https://www.cnblogs.com/AwD-/p/6349972.html
Copyright © 2020-2023  润新知