zoukankan      html  css  js  c++  java
  • 【JZOJ4888】【NOIP2016提高A组集训第14场11.12】最近公共祖先

    题目描述

    YJC最近在学习树的有关知识。今天,他遇到了这么一个概念:最近公共祖先。对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。YJC很聪明,他很快就学会了如何求最近公共祖先。他现在想寻找最近公共祖先有什么性质,于是他提出了这样的一个问题:n层的满k叉树T,求对于每一对(i,j)(1≤i,j≤T的点数),LCA(T,i,j)的深度的和是多少。这个数字n层的满k叉树指一棵带标号的有根树,深度为i(0≤i

    数据范围

    ​对于30%的数据,满足2≤n,k≤8;
    对于50%的数据,满足2≤n,k≤1000000;
    对于100%的数据,满足2≤n,k≤998244351。

    解法

    设f[i]表示贡献为i的点对的个数,那么对于一棵n层k叉树:

    f[i]=(kni1k1)2k(kni11k1)2


    ans=i=1n1ikif[i]=i=1n1iki((kni1k1)2k(kni11k1)2)=k2n(n1i1iki)k2n1(n1i1iki)+(1k)(n1i=1iki)(k1)2

    详细推的过程看图:
    这里写图片描述

    代码

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #define ll long long
    #define sqr(x) ((x)*(x))
    using namespace std;
    const char* fin="lca.in";
    const char* fout="lca.out";
    const ll inf=0x7fffffff;
    const ll mo=998244353;
    ll n,m,i,j;
    ll ans,tmp,tmd;
    ll qpower(ll a,ll b){
        ll c=1;
        while (b){
            if (b&1) c=c*a%mo;
            a=a*a%mo;
            b>>=1;
        }
        return c;
    }
    ll N(ll a){
        return qpower(a,mo-2);
    }
    int main(){
        freopen(fin,"r",stdin);
        freopen(fout,"w",stdout);
        cin>>n>>m;
        tmp=((n*(qpower(m,n)-1)%mo*N(m-1)%mo-((qpower(m,n+1)-1)*N(m-1)%mo-n-1)*N(m-1)%mo)%mo+mo)%mo;
        tmd=(n*(qpower(m,n)-1)%mo*N(m-1)%mo-n-tmp)%mo*N(qpower(m,n))%mo;
        ans=N(sqr(m-1)%mo)*(qpower(m,2*n)*tmd%mo-qpower(m,2*n-1)*tmd%mo+(1-m)*tmp%mo)%mo;
        ans=(ans%mo+mo)%mo;
        cout<<ans<<endl;
        return 0;
    }

    启发

    往死里推,正难则反。

  • 相关阅读:
    JavaScript中的valueOf与toString方法
    CSS的历史与工作原理
    Javascript让你的网页标题飘动起来
    getElementsByClassName的原生实现
    JavaScript去除空格trim()的原生实现
    JavaScript截取中英文字符串
    Keras函数式API介绍
    R语言kohonen包主要函数介绍
    在Shell直接运行Python命令并显示
    GitHub Pages
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6714836.html
Copyright © 2011-2022 走看看