zoukankan      html  css  js  c++  java
  • 黑红树

    问题 B: 黑红树

    时间限制: 2 Sec  内存限制: 256 MB

    题目描述

    Mz们在czy的生日送他一个黑红树种子……czy种下种子,结果种子很快就长得飞快,它的枝干伸入空中看不见了……

    Czy发现黑红树具有一些独特的性质。

    1、 这是二叉树,除根节点外每个节点都有红与黑之间的一种颜色。

    2、 每个节点的两个儿子节点都被染成恰好一个红色一个黑色。

    3、 这棵树你是望不到头的(树的深度可以到无限大)

    4、 黑红树上的高度这样定义:h(根节点)=0,h[son]=h[father]+1。

    Czy想从树根顺着树往上爬。他有p/q的概率到达红色的儿子节点,有1-p/q的概率到达黑色节点。但是他知道如果自己经过的路径是不平衡的,他会马上摔下来。一条红黑树上的链是不平衡的,当且仅当红色节点与黑色节点的个数之差大于1。现在他想知道他刚好在高度为h的地方摔下来的概率的精确值a/b,gcd(a,b)=0。那可能很大,所以他只要知道a,b对K取模的结果就可以了。另外,czy对输入数据加密:第i个询问Qi真正大小将是给定的Q减上一个询问的第一个值a%K.


    输入

    第一行四个数p,q,T,k,表示走红色节点概率是p/q,以下T组询问,答案对K取模。接下来T行,每行一个数 Q,表示czy想知道刚好在高度Q掉下来的概率(已加密)

    输出

    输出T行,每行两个整数,表示要求的概率a/b中a%K和b%K的精确值。如果这个概率就是0或1,直接输出0 0或1 1(中间有空格)。

    样例输入

    样例输入1									样例输入2
    2 3 2 100											2 3 2 20
    1													4
    2													6

    样例输出

    样例输出1									样例输出2
    0 0													0 1
    5 9	

    提示


    对于30%数据,p,q<=5,T<=1000,K<=127,对于任意解密后的Q,有Q<=30



    对于60%数据,p,q<=20,T<=100000,K<=65535,对于任意解密后的Q,有Q<=1000



    对于100%数据,p,q<=100,T<=1000000, K<=1000000007,对于任意解密后的Q,有Q<=1000000


    对于100%数据,有q>p,即0<= p/q<=1

        首先,题目中说了,要红点与黑点个数差是二就会掉下去,那么在两点相差1时,他们一定是在奇数层,因为n+n+1一定是奇数,那么他们只可能在偶数层掉下去,之后两层两层的找,若是奇数层输出0 0,偶数层每走一个偶数层,连续两个红的概率是p/q*p/q,黑的概率是(1-p/q)*(q-p/q),那么一层活下来的概率就是1-……,然后根据这个化简得到一个递推式子,打表的到每一个偶数层的活的概率,然后在查询的时候,用上一个偶数层活的概率乘死的概率就是答案

     1 #include<cmath>
     2 #include<ctime>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<iostream>
     7 #include<algorithm>
     8 using namespace std;
     9 int p,q,T,mo;
    10 int gcd(int a,int b){
    11     if(a%b==0) return b;
    12     return gcd(b,a%b);
    13 }
    14 long long f1[1000010],f2[1000010];
    15 void clear(){
    16     int tt=gcd(q,p);
    17     q/=tt; p/=tt;
    18     f1[0]=f2[0]=1;
    19     f1[2]=2*p*(q-p);
    20     f2[2]=q*q;
    21     tt=gcd(2*p*(q-p),q*q);
    22     f1[2]/=tt; f2[2]/=tt;
    23     int aaa=f1[2],bbb=f2[2];
    24     //cout<<"f== "<<f1[2]<<"  "<<f2[2]<<endl;
    25     for(int i=4;i<=1000000;i+=2){
    26         f1[i]=f1[i-2]*aaa;
    27         f1[i]%=mo;
    28         f2[i]=f2[i-2]*bbb;
    29         f2[i]%=mo;
    30     }
    31 }
    32 int main(){
    33     //freopen("a.in","r",stdin);
    34     //freopen("a.out","w",stdout);
    35     scanf("%d%d%d%d",&p,&q,&T,&mo);
    36     clear();
    37     long long x,y,z=0,cc,ans1=0;
    38     cc=gcd(p*p+(q-p)*(q-p),q*q);
    39     for(int i=1;i<=T;i++){
    40         scanf("%lld",&x);
    41         x-=ans1;
    42         if(x==0 || (x&1)){
    43             ans1=0;
    44             printf("0 0
    ");
    45         }
    46         else{
    47             long long aa,bb;
    48             aa=(p*p+(q-p)*(q-p))%mo;
    49             bb=q*q;
    50             aa/=cc; bb/=cc;
    51             y=(f1[x-2]*aa)%mo;
    52             z=(f2[x-2]*bb)%mo;
    53             //cout<<f1[x-2]<<"  "<<f2[x-2]<<endl;
    54             printf("%lld %lld
    ",y,z);
    55             ans1=y;
    56         }
    57     }
    58     return 0;
    59 }
    60 /*
    61 2 3 2 100
    62 1 
    63 2
    64 */
  • 相关阅读:
    【OpenCV学习笔记1】OpenCV 编程简介[轉]
    latex与word比较
    【C/C++语法外功】传值&传引用&传指针
    ellen 纽奥良大学演讲
    华侨大学50年校庆校长讲话
    【专题】工业相机接口
    【C/C++参考手册】C++资源之不完全导引[轉]
    比尔盖茨_哈佛演说
    拉里.埃里森_耶鲁大学演讲
    【OpenCV学习笔记2】OpenCV 完全安装 新增VS2010+OpenCV2.1,新增VS2010+OpenCV2.3.1
  • 原文地址:https://www.cnblogs.com/FOXYY/p/7258164.html
Copyright © 2011-2022 走看看