• 黑红树


    题目描述

    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 3 2 100


    样例输出1
    0 0 
    5 9

    样例输入2

    2 3 2 20

    4

    6

    样例输出2

    0 1

    0 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

    【题解】

        每日一道概率题。非常愉快的调出来10分,在考试过程中打了分数加减乘约分,简直360度复习小学知识,虽然调试过程中发现了一些规律但是并没有什么用,没有再往下一步走。虽然题目叫黑红树,可是和某数据结构好像毫无关系。每日一跳的推式子大坑,但是我推的还是不够优美,实现也很虚,除了某ryf大佬A掉之外也只有本蒟蒻水了十分,膜一发大佬。

        正解用到两个概率,在每两层不掉下的概率(p^2+(p-q)^2)/q^2,掉下的概率自然是1-不掉下概率。为什么都以两次为度量?在奇数层是不可能掉下去的,因为奇数层一定从红黑点相等的偶数层转移过来,至多差1个。这样只要询问的是奇数层就直接输出0 0,偶数层结果为不掉下概率^(层数/2-1)*掉下概率。在一切递推开始之前就把两个概率约到最简,之后就可以放心取模了。小学做作业的时候天天念着的规律,这么多年还真有些忘了啊。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int sj=1000010;
    int p,q,ca,k,ww;
    long long qu,jz,a,b,c,d,fmf[sj],fzf[sj],afz,afm,la;
    long long gcd(long long x,long long y)
    {
        if(!y) return x;
        return gcd(y,x%y);
    }
    void yf(long long &x,long long &y)
    {
        long long temp=gcd(x,y);
        if(temp!=1&&temp!=0)
        {
           x/=temp;
           y/=temp;
        }
    }
    void dt()
    {
         for(int i=jz+1;i<=la;i++)
         {
            fmf[i]=fmf[i-1]*d%k;
            fzf[i]=fzf[i-1]*c%k;
         }
         jz=la;
    }
    int main()
    {
        //freopen("t2.txt","r",stdin);
        //freopen("brtree1.in","r",stdin);
        //freopen("brtree.out","w",stdout);
        scanf("%d%d%d%d",&p,&q,&ca,&k);
        ww=q-p;
        a=p*p+ww*ww;
        b=q*q;
        d=b;
        c=b-a;
        yf(c,d);
        yf(a,b);
        fmf[1]=d;
        fzf[1]=c;
        fmf[0]=1;
        fzf[0]=1;
        jz=1;
        for(int i=1;i<=ca;i++)
        {
           scanf("%lld",&qu);
           qu-=la;
           if(qu<=0)  
           {
             printf("0 0
    ");
             la=0;
             continue;
           }
           if(qu&1)
           {
             printf("0 0
    ");
             la=0;
             continue;
           }
           la=(qu>>1)-1;
           if(jz<la) dt();
           afm=fmf[la]*b;
           afz=fzf[la]*a;
           afz%=k;
           afm%=k;
           printf("%lld %lld
    ",afz,afm);
           la=afz;
        }
        //while(1);
        return 0;
    }
  • 相关阅读:
    phpexcel 导入超过26列、处理时间格式
    PDO::__construct(): Server sent charset (255) unknown to the client. Please, report to the developers
    关于微信支付服务器证书更换的提醒
    PHP微信开发之模板消息回复
    js---用对象来放置变量和方法
    electron---更改安装图标
    css---【vw,vh】进行自适应布局单位
    vue---父子组件之间的通信【props,$refs、$emit】
    vue---props进行双向数据绑定报错
    ES6----拓展运算符 三个点【...】
  • 原文地址:https://www.cnblogs.com/moyiii-/p/7252679.html
Copyright © 2020-2023  润新知