1 条题解

  • 0
    @ 2022-6-8 9:17:22
    /*luoguP1235 AC code, Copyright © JSSY(i.e. jiangyougogogo)*/
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<vector>
    #define hk 310
    using namespace std;
    struct DB{short N[hk];};//正序存储定点小数,N[0]代表位数,N[1]是整数部分,N[2]到N[N[0]]是小数部分
    DB div(DB x,int y){//高精度除法
        int rem,flg=0;DB z;if(!x.N[1]&&x.N[0]==1)return x;
        for(memset(z.N,0,sizeof z.N),z.N[z.N[0]=1]=x.N[1]/y,rem=x.N[1]%y;(rem||!flg)||z.N[0]<x.N[0];z.N[0]++){
            z.N[z.N[0]+1]=(rem*10+x.N[z.N[0]+1])/y;
            rem=(rem*10+x.N[z.N[0]+1])%y;if(z.N[z.N[0]+1])flg=1;
        }return z;
    }DB plu(DB x,DB y){//高精度加法
        int i=max(x.N[0],y.N[0]);DB z;for(memset(z.N,0,sizeof z.N);i;i--){
            z.N[i-1]+=(z.N[i]+x.N[i]+y.N[i])/10;
            z.N[i]=(z.N[i]+x.N[i]+y.N[i])%10;
        }for(z.N[0]=max(x.N[0],y.N[0]);z.N[0]>1&&!z.N[z.N[0]];z.N[0]--);
        return z;
    }void wri(DB x){//输出,先输出百分数的整数部分,再输出小数部分
        int i,t=0;for(i=1;i<4;i++)t=t*10+x.N[i];
        printf("%d",t);if(x.N[0]<4){puts("%");return;}
        for(putchar('.'),i=4;i<=x.N[0];i++)printf("%d",x.N[i]);puts("%");return;
    }
    vector<int>eg[hk];int n,k,i,j,x,y,z,f[hk][2],m,q[hk],la[hk],to[hk],hd,tl,tt;
    bool iss[hk],lab[hk][hk],inq[hk];DB F[hk][hk];
    DB C(int x,int y){//记忆化搜索
        if(lab[x][y])return F[x][y];//计算过就直接把答案拿来
        if(la[x]>la[y]||!iss[y])F[x][y]=F[y][x]=div(plu(C(f[x][0],y),C(f[x][1],y)),2);
        else F[x][y]=F[y][x]=div(plu(C(x,f[y][0]),C(x,f[y][1])),2);//选辈分低的向祖先方向继续搜
        lab[x][y]=lab[y][x]=1;return F[x][y];
    }int main(){
    for(scanf("%d%d",&n,&k),i=0;i<k;i++)
    scanf("%d%d%d",&x,&y,&z),f[x][0]=y,f[x][1]=z,iss[x]=1,eg[y].push_back(x),eg[z].push_back(x),to[x]+=2;
        for(i=1;i<=n;i++)if(!iss[i])q[++tl]=i,la[i]=inq[i]=1;//类似拓扑的方法处理辈分,先把没有父母(即iss[i]==0)的那些点记作第一层,计算la[]表示层数,分层
        for(hd=0;hd^tl;){
            for(hd++,i=eg[q[hd]].size()-1;i+1;i--)if(!(--to[tt=eg[q[hd]][i]])&&!inq[tt])
                q[++tl]=tt,inq[tt]=1,la[tt]=la[q[hd]]+1;
    }//BFS拓扑
    for(i=1;i<=n;i++)for(j=1;j<=n;j++){
            if(!iss[i]&&!iss[j])F[i][j].N[1]=0,F[i][j].N[0]=1,lab[i][j]=1;
            if(i==j)F[i][j].N[1]=1,F[i][j].N[0]=1,lab[i][j]=1;
    }//赋初值,其中lab[i][j]表示当前位置有没有被计算过
    for(scanf("%d",&m);m;m--){
            scanf("%d%d",&x,&y);
            wri(C(x,y));//计算即输出
        }return 0;
    }
    
    • 1

    信息

    ID
    236
    时间
    1000ms
    内存
    125MiB
    难度
    6
    标签
    递交数
    1
    已通过
    1
    上传者