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

    题目描述

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

    数据范围

    对于100%的数据n<=5000。

    =w=

    性质:
    以任意一个白点为根作子树时,在这棵子树中,白点和黑点的数量随深度呈斐波那契数列形态。
    设当深度为i时,白点数量为w[i],白点数量前缀和为sum[i],黑点数量前缀和为f[i]。这些可以O(n)预处理。


    我们对贡献分门别类:

    1.lca是白点类
    

    显然当两个点的lca是白点时,其中一个点是这个白点。
    我们以每一个白点为根做子树来计算答案,具体地:

    我们枚举一个i,表示这两个点的距离。
    所有深度在[1,ni]的白点都拥有与它距离为i的儿子,所以都可以对ans[i]作贡献。
    然后这些白点的贡献都是相同的,而且都是w[i+1]

    那么对于一个i,ans[i]+=sum[ni]w[i+1]

    2.lca是黑点类
    

    同样枚举一个i和一个j,其中一个结点与lca距离为i,另一个结点与lca距离为j。
    所有深度在[1,nmax(i,j)]的黑点都可以贡献ans[i+j]

    所以对于i,j,ans[i+j]+=f[nmax(i,j)]w[i]w[j+1]

    代码

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #define ll long long
    #define ln(x,y) (ll(log(x)/log(y)))
    using namespace std;
    const char* fin="raviel.in";
    const char* fout="raviel.out";
    const ll inf=0x7fffffff;
    const ll mo=123456789;
    const ll maxn=10007;
    ll n,i,j,k;
    ll f[maxn],g[maxn],sum[maxn],ans[maxn];
    int main(){
        freopen(fin,"r",stdin);
        freopen(fout,"w",stdout);
        scanf("%d",&n);
        f[1]=0;
        f[2]=1;
        for (i=3;i<maxn;i++) f[i]=(f[i-2]+f[i-1])%mo;
        for (i=1;i<maxn;i++) f[i]=(f[i]+f[i-1])%mo;
        g[1]=1;
        g[2]=0;
        for (i=3;i<maxn;i++) g[i]=(g[i-2]+g[i-1])%mo;
        for (i=1;i<maxn;i++) sum[i]=(sum[i-1]+g[i])%mo;
        for (i=1;i<n;i++){
            k=n-i;
            ans[i]=(ans[i]+sum[k]*g[i+1])%mo;
        }
        for (i=1;i<n;i++)
            for (j=1;j<n;j++){
                k=n-max(i,j);
                ans[i+j]=(ans[i+j]+f[k]*g[i]%mo*g[j+1])%mo;
            }
        for (i=1;i<=n*2;i++) printf("%lld ",ans[i]);
        printf("
    ");
        return 0;
    }

    =o=

    我认为在做这道题的时候的瓶颈是正确地对贡献分门别类。
    然后要先枚举距离,在根据这个距离计数。
    由于问题是每种距离的个数,那么这个问题决定了这道题必须先枚举距离来计数的特点。
    至今还在纠结正确的枚举方式是怎样。
    还有待决定。

  • 相关阅读:
    121.买卖股票 求最大收益1 Best Time to Buy and Sell Stock
    409.求最长回文串的长度 LongestPalindrome
    202.快乐数 Happy Number
    459.(KMP)求字符串是否由模式重复构成 Repeated Substring Pattern
    326.是否为3的平方根 IsPowerOfThree
    231.是否为2的平方根 IsPowerOfTwo
    461.求两个数字转成二进制后的“汉明距离” Hamming Distance
    206.反转单链表 Reverse Linked List
    448. 数组中缺少的元素 Find All Numbers Disappeared in an Array
    常见表单元素处理
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6714819.html
Copyright © 2011-2022 走看看