zoukankan      html  css  js  c++  java
  • 【NOIP2017提高组模拟12.10】幻魔皇

    题目

    幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对。
    所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子。神奇的节点对则是指白色节点对。
    请问对于深度为n的斐波那契树,其中距离为i的神奇节点对有多少个?拉比艾尔需要你对于1<=i<=2n的所有i都求出答案。

    分析

    这里写图片描述
    我们找一找每层黑点和白点的规律

    层数 白点数 黑点数
    1 1 0
    2 0 1
    3 1 1
    4 1 2
    5 2 3
    ......

    又发现一棵以白点为根的子树和原树结构一样,
    一棵以黑点为根的子树和从第二层开始原树结构一样,
    预处理出每层黑白点的个数,个数前缀和以及每层黑白点的个数,个数前缀和。
    那么假设神奇点对的lca为白点,那么lca一定是点对中的一个点(观察结构得出),
    枚举距离为i,那么个数就是一颗以白点为根的子树第i+1层的白点个数,乘以有多少个这样的子树。
    同样,假设神奇点对的lca为黑点,
    枚举两个点到达lca的距离分别为i和j,那么个数就是一颗以黑点为根的子树第i+1层的白点个数,乘以一颗以黑点为根的子树第i+1层的白点个数,乘以有多少个这样的子树。

    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    const int maxlongint=2147483647;
    const long long mo=123456789;
    const int N=5005;
    using namespace std;
    long long w[N],sum[N],n,ans[N*2],b[N],sum1[N];
    int main()
    {
    	scanf("%lld",&n);
    	w[1]=1;
    	w[2]=0;
    	w[3]=1;
    	for(int i=4;i<=n;i++) w[i]=(w[i-1]+w[i-2])%mo;
    	for(int i=1;i<=n;i++) sum[i]=(sum[i-1]+w[i])%mo;
    	b[1]=0;
    	b[2]=1;
    	for(int i=3;i<=n;i++) b[i]=(b[i-1]+b[i-2])%mo;
    	for(int i=1;i<=n;i++) sum1[i]=(sum1[i-1]+b[i])%mo;
    	for(int i=1;i<=n;i++) 
    		ans[i]=sum[n-i]*w[i+1]%mo;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    		{
    			ans[i+j]=(ans[i+j]+sum1[n-max(i,j)]*w[i]%mo*w[j+1]%mo)%mo;
    		}
    	for(int i=1;i<=n*2;i++) printf("%lld ",ans[i]);
    }
    
    
  • 相关阅读:
    图论03—随意两点间最短距离及路径(改进)
    &lt;转&gt;Openstack ceilometer 宿主机监控模块扩展
    【从零学习openCV】IOS7下的openCV开发起步(Xcode5.1.1&amp;openCV2.49)
    零基础学python-6.2 共享引用
    hdu 2191 悼念512汶川大地震遇难同胞——珍惜如今,感恩生活
    Android与设计模式——单例(Singleton)模式
    SpringMVC+Jquery -页面异步载入数据
    hdoj Let the Balloon Rise
    openStack使用宿主机监控
    winscp自动执行脚本
  • 原文地址:https://www.cnblogs.com/chen1352/p/9066607.html
Copyright © 2011-2022 走看看