【NOIP2017提高组模拟12.10】幻魔皇
2016-12-12 22:15
176 查看
Description
幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对。所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子。神奇的节点对则是指白色节点对。
请问对于深度为n的斐波那契树,其中距离为i的神奇节点对有多少个?拉比艾尔需要你对于1<=i<=2n的所有i都求出答案。
Solution
把一段路径拆成两段,x->lca,lca->y。我们考虑lca的颜色。
当lca为白色的时候,那么只会有从下面到lca的路径,那么个数就是第i层白色节点的个数(找一下规律是斐波那契额数列)
当lca为黑色的时候,我们枚举左儿子的长度k,那么右儿子的长度就是i-k,然后求出这些白色节点的个数然后再乘以黑色节点的个数[枚举有儿子距离有i-k和k,那么把这个层数一下的节点加起来](也是斐波那契额数列,但是要求一下前缀和)。
但是会有一个问题,就是直接求的话,右儿子中有一些节点是左儿子里面的,那么就会算重。
所以要减去左儿子重复的情况,那么就设左儿子是白的,那么从右儿子的黑的开始,右儿子就算i-k-1深度的白节点数。
Code
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; const int maxn=10007,mo=123456789; long long i,j,k,l,t,n,m,ans,yi,er; long long f[maxn],a[maxn],g[maxn]; int main(){ freopen("raviel.in","r",stdin); freopen("raviel.out","w",stdout); scanf("%lld",&n); f[0]=1,g[1]=1;a[1]=1; fo(i,2,n)f[i]=(f[i-1]+f[i-2])%mo,g[i]=(g[i-1]+g[i-2])%mo,a[i]=(a[i-1]+g[i])%mo; n--; fo(i,1,2*n+2){ t=0; fo(j,0,n-i)t=(t+f[j])%mo; ans=t*f[i]%mo; yi=(i>n)?n:i; er=(i-n>1)?i-n:1; fo(j,er,yi-1)ans=(ans+f[j]*f[i-j-1]%mo*a[min(n-j,n-i+j)]%mo)%mo; printf("%lld ",ans); } }
相关文章推荐
- 【NOIP2017提高组模拟12.10】幻魔皇
- 【NOIP2017提高组模拟12.10】幻魔皇
- 【NOIP2017提高组模拟12.10】幻魔皇
- JZOJ 4921. 【NOIP2017提高组模拟12.10】幻魔皇
- 【NOIP2017提高组模拟12.10】神炎皇
- JZOJ 4919.【NOIP2017提高组模拟12.10】神炎皇
- 【NOIP2017提高组模拟12.10】神炎皇
- 【JZOJ4921】【NOIP2017提高组模拟12.10】幻魔皇
- 幻魔皇 【NOIP2017提高组模拟12.10】
- 神炎皇【NOIP2017提高组模拟12.10】
- 【NOIP2017提高A组模拟9.14】生命之树 (dsu on tree+trie)
- 【NOIP2017提高A组模拟9.21】传送蛋糕
- 【NOIP2017提高组模拟6.29】小T的钢琴
- 【NOIP2017提高A组模拟10.7】Adore
- JZOJ 100037【NOIP2017提高A组模拟7.11】后缀数组
- 【NOIP2017提高A组模拟10.8】Lost My Music
- 【NOIP2017提高组模拟12.18】C
- 【NOIP2017提高A组模拟8.25】夜莺与玫瑰
- 【NOIP2017提高A组模拟10.7】Repulsed
- 【NOIP2017提高A组模拟8.22】世界线