zoukankan      html  css  js  c++  java
  • 1775:梦中漫步

    1775:梦中漫步

    时间限制: 1000 ms         内存限制: 262144 KB
    【题目描述】

    梦游中的你来到了一棵N个结点的树上。

    你一共做了Q个梦,每个梦需要你从点u走到点v之后才能苏醒。

    由于你正在梦游,所以每到一个结点后,你会在它连出去的边中等概率地选择一条边走过去。

    为了确保第二天能够准时到校,你要求出每个梦期望经过多少条边才能苏醒。为了避免精度误差,你要输出答案模1e9+7的结果。
    【输入】

    第一行两个整数分别代表N和Q。

    接下来N-1行,每行两个整数u,v代表树中的一条边。

    接下来Q行,每行两个整数代表询问的u,v。
    【输出】

    一共Q行, 每行一个整数代表答案。
    【输入样例】

    4 2
    1 2
    2 3
    3 4
    1 4
    3 4

    【输出样例】

    9
    5

    【提示】

    【数据规模】

    对于20%的数据,N≤10。

    对于40%的数据,N≤1000。

    另有20%的数据,保证给定的树是一条链。

    对于100%的数据,N≤100000,Q≤100000。

    【题解】

    类似于囧哥t4的套路。

    定义dp[i]为从i节点走到它的父亲节点期望步数,siz[i]为i节点的亲儿子个数+1。

    dp[i]=frac{1}{siz[i]}*1+sum (1+dp[v]+dp[i])*frac{1}{siz[i]}。v是i的所有儿子。

    移项化简得dp[i]=sum dp[v]*+siz[i]。

    同理定义sh[i]表示i的祖先走到i的期望步数,求法类似。

    最后倍增处理一哈,询问即可nlogn。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    const int mo=1e9+7;
    int n,q,last[N],size,siz[N],dp[N],sh[N],f[N][20],g[N][20],h[N][20],dep[N];
    struct pigu
    {
        int dao,ne;
    }a[N<<1];
    inline void lingjiebiao(int x,int y)
    {
        a[++size].dao=y;
        a[size].ne=last[x];
        last[x]=size;
    }
    inline int read()
    {
        char c=getchar();
        int x=0,f=1;
        while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
        while(isdigit(c)) {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
        return x*f;
    }
    inline void dfs(int now,int fa)
    {
        int daan=0;f[now][0]=fa;dep[now]=dep[fa]+1;
        for(int i=1;f[f[now][i-1]][i-1];i++) f[now][i]=f[f[now][i-1]][i-1];
        for(int i=last[now];i;i=a[i].ne)
        {
            if(a[i].dao==fa) continue; 
            siz[now]++;siz[a[i].dao]++;
            dfs(a[i].dao,now);
            daan+=dp[a[i].dao];
        }
        if(siz[now]==1) dp[now]=1;
        else dp[now]=siz[now]+daan;
    }
    inline void dfs2(int now,int fa)
    {
        int huo=0;
        for(int i=last[now];i;i=a[i].ne)
        {
            if(a[i].dao==fa) continue;
            huo+=dp[a[i].dao];
        }
        if(fa) huo+=sh[now];
        for(int i=last[now];i;i=a[i].ne)
            if(a[i].dao!=fa)
                sh[a[i].dao]=siz[now]+huo-dp[a[i].dao];
        for(int i=last[now];i;i=a[i].ne)
            if(a[i].dao!=fa)
                dfs2(a[i].dao,now);
    }
    inline void dfs3(int now)
    {
        g[now][0]=dp[now];h[now][0]=sh[now];
        for(int i=1;f[now][i];i++) g[now][i]=(g[now][i-1]+g[f[now][i-1]][i-1])%mo,h[now][i]=(h[now][i-1]+h[f[now][i-1]][i-1])%mo;
        for(int i=last[now];i;i=a[i].ne)
        {
            if(f[now][0]==a[i].dao) continue; 
            dfs3(a[i].dao);
        }
    }
    inline int get_lca(int x,int y)
    {
        if(dep[x]<dep[y]) swap(x,y);
        for(int i=19;i>=0;i--) 
            if(dep[f[x][i]]>=dep[y]) x=f[x][i];
        if(x==y) return x;
        for(int i=19;i>=0;i--)
            if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    int main()
    {
        n=read();q=read();    
        for(int i=1,x,y;i<=n-1;i++)
        {
            x=read();y=read();
            lingjiebiao(x,y);
            lingjiebiao(y,x);
        }
        dfs(1,0);    
        dfs2(1,0);
        dfs3(1);
        for(int i=1,x,y;i<=q;i++)
        {
            int ans=0;
            x=read();y=read();
            int lca=get_lca(x,y);
            for(int i=19;i>=0;i--)
                if(dep[f[x][i]]>=dep[lca])
                    ans+=g[x][i],ans%=mo,x=f[x][i];
            for(int i=19;i>=0;i--)
                if(dep[f[y][i]]>=dep[lca])
                    ans+=h[y][i],ans%=mo,y=f[y][i];
            cout<<ans<<"
    ";
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    第01组 Alpha冲刺 总结
    第01组 Alpha冲刺 (6/6)
    小黄衫买家秀及获奖感言
    软工实践个人总结
    实验 7:OpenDaylight 实验——Python 中的 REST API 调用
    实验 6:OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发
    实验 5:OpenFlow 协议分析和 OpenDaylight 安装
    SDN实验 4:Open vSwitch 实验——Mininet 中使用 OVS 命令
    实验 3:Mininet 实验——测量路径的损耗率
    2020软件工程个人编程作业一:统计分析GitHub 的用户行为数据
  • 原文地址:https://www.cnblogs.com/betablewaloot/p/12247263.html
Copyright © 2011-2022 走看看