zoukankan      html  css  js  c++  java
  • 【Luogu】P3211XOR和路径(高斯消元)

      题目链接

      唉我个ZZ……

      首先考虑到异或是可以每一位分开算的

      好的以后再碰见位运算题我一定先往按位开车上想

      然后设f[i]为从i点出发到终点是1的概率

      高斯消元解方程组即可。

      

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<bitset>
    #define maxn 200
    #define maxm 50020
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    inline int calc(int a,int b){    return (b>>a)&1;    }
    
    struct Edge{
        int next,to,val,dis;
    }edge[maxm*2];
    int head[maxn],num;
    inline void add(int from,int to,int val){
        edge[++num]=(Edge){head[from],to,val,0};
        head[from]=num;
    }
    
    double s[maxn][maxn];
    
    double dl[maxn];
    double ans[maxn];
    
    void gauss(int n){
        for(int i=1;i<=n;++i){
            int now=i;
            for(int j=now;j<=n;++j)
                if(fabs(s[j][i])>fabs(s[now][i]))    now=j;
            if(now!=i)    swap(s[i],s[now]);
            double div=s[i][i];
            for(int j=i;j<=n+1;++j)    s[i][j]/=div;
            for(int j=i+1;j<=n;++j){
                double ret=s[j][i];
                for(int k=i;k<=n+1;++k){
                    s[j][k]-=ret*s[i][k];
                }
            }
        }
        ans[n]=s[n][n+1];
        for(int i=n-1;i;--i){
            double now=0;
            for(int j=i+1;j<=n;++j)    now+=ans[j]*s[i][j];
            ans[i]=s[i][n+1]-now;
        }
    }
    
    int main(){
        int n=read(),m=read();
        for(int i=1;i<=m;++i){
            int from=read(),to=read(),val=read();
            dl[from]++;    add(from,to,val);
            if(from!=to){
                dl[to]++;
                add(to,from,val);
            }
        }
        double Ans=0;
        for(int i=0;i<32;++i){
            memset(s,0,sizeof(s));
            for(int j=1;j<=n;++j)    s[j][j]=1;
            for(int j=1;j<=num;++j)    edge[j].dis=calc(i,edge[j].val);
            for(int j=1;j<n;++j)
                for(int k=head[j];k;k=edge[k].next){
                    int to=edge[k].to;
                    if(edge[k].dis){
                        s[j][to]+=1.0/dl[j];    s[j][n+1]+=1.0/dl[j];
                    }
                    else s[j][to]-=1.0/dl[j];
                }
            //for(int j=1;j<=n;++j,printf("
    "))
            //    for(int k=1;k<=n+1;++k)    printf("%.3lf ",s[j][k]);
            gauss(n);
            //printf("
    ");
            Ans+=ans[1]*(1<<i);
        }
        printf("%.3lf",Ans);
        return 0;
    }
  • 相关阅读:
    How do I add elements to a Scala List?
    Can you share some Scala List class examples?
    How to add elements to a List in Scala
    数据结构和算法学习三,之递归和堆栈
    数据结构和算法学习二,之循环和递归
    数据结构和算法学习一,开篇
    Android Skia和2D图形系统 .
    EGL接口介绍-----Android OpenGL ES底层开发
    OpenGL网络资源
    OpenGL—Android 开机动画源码分析二
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8823543.html
Copyright © 2011-2022 走看看