zoukankan      html  css  js  c++  java
  • [HNOI2011]XOR和路径

    [HNOI2011]XOR和路径

    BZOJ
    luogu
    感觉跟[HNOI2013]游走差不多a...
    然而就是这个异或要一位一位做
    设f[k][u]表示u点到n的路径异或和二进制第k位为1的概率
    考虑枚举u的出边,w(u,v)表示这条边第k位是0还是1

    [f[u]=sum_{w(u,v)=0}frac{f[v]}{d[u]}+sum_{w(u,v)=1}frac{1-f[v]}{d[u]} ]

    处理好系数矩阵高斯消元
    注意重自环只连单向边就行了
    等等,还有f[n]=0

    #include<bits/stdc++.h>
    using namespace std;
    const int _=105;
    const double eps=1e-10;
    int re(){
        int x=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*w;
    }
    int n,m,cnt;
    int h[_],d[_];
    double Ans;
    double a[_][_],b[_],ans[_];
    struct edge{int to,next,w;}e[20005];
    void link(int u,int v,int w){
        e[++cnt]=(edge){v,h[u],w};
        h[u]=cnt;d[u]++;
    }
    void gauss(){
        for(int i=1;i<=n;i++){
            if(fabs(a[i][i])<eps)
                for(int j=i+1;j<=n;j++)
                    if(fabs(a[j][i])>eps){
                        swap(a[i],a[j]);swap(b[i],b[j]);break;
                    }
            if(fabs(a[i][i])<eps)continue;
            for(int j=i+1;j<=n;j++){
                if(fabs(a[j][i])<eps)continue;
                double s=a[j][i]/a[i][i];
                for(int k=i;k<=n;k++)a[i][k]*=s;b[i]*=s;
                for(int k=i;k<=n;k++)a[j][k]-=a[i][k];b[j]-=b[i];
            }
        }
        for(int i=n;i>=1;i--){
            ans[i]=b[i]/a[i][i];
            for(int j=1;j<i;j++)b[j]-=a[j][i]*ans[i];
        }
    }
    int main(){
        n=re(),m=re();
        for(int i=1,u,v,w;i<=m;i++){
            u=re(),v=re(),w=re();
            if(u^v)link(u,v,w),link(v,u,w);
            else link(u,v,w);
        }
        for(int k=0;k<=29;k++){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            memset(ans,0,sizeof(ans));
            for(int i=1;i<n;i++){
                a[i][i]=1;
                for(int j=h[i];j;j=e[j].next){
                    int v=e[j].to;
                    if(e[j].w>>k&1)a[i][v]+=1.0/d[i],b[i]+=1.0/d[i];
                    else a[i][v]-=1.0/d[i];
                }
            }
            a[n][n]=1;gauss();Ans+=(1<<k)*ans[1];
        }
        printf("%.3f
    ",Ans);return 0;
    }
    
  • 相关阅读:
    第一阶段-意见评论
    团队冲刺第15天
    团队冲刺第14天
    第十三周进度报告
    团队冲刺第13天
    团队冲刺第12天
    团队冲刺第11天
    SCRUM第二阶段第九天
    SCRUM第二阶段第八天
    SCRUM第二阶段第七天
  • 原文地址:https://www.cnblogs.com/sdzwyq/p/9837054.html
Copyright © 2011-2022 走看看