• 【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=

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

  • 相关阅读:
    扩展LVM 逻辑卷存储空间
    Linux Shell远程执行命令(命令行与脚本方式)
    vsftpd FTP服务器配置
    初识小米Minos
    使用Libpng库实现Tiny6410显示PNG图片
    uCos-II内存管理
    应用程序调用tslib出现segmentation fault
    Linux-2.6.39在Tiny6410上的移植
    Linux-2.6.39在Tiny6410上的移植
    Tiny6410移植tslib
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6714819.html
Copyright © 2020-2023  润新知