• 黑红树


    背景

    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
    2
    样例输入2
    2 3 2 20
    4
    6

    样例输出

    样例输出1	
    0 0
    5 9
    样例输出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

    solution:

     解法1:

    考试时想的(能过8个点,手动开O3能A)

    把图全画出来,你会得到一个通项公式:

    f[i]=( (2*p*(q-p))^(h/2-1) * (2*p^2-2*q*p+q^2) ) / q^h

        =0   (h为奇数)

    然后分解质因数约分即可

    解法2:

    我们发现h为奇数时只有可能  abs(黑点数-红点数)=1,所以 f[h]=0

    当h为偶数时,

    我们发现 (p/q)+(1+p/q)=(p^2+(q-p)^2)/q^2 为走两个高度时不掉的概率   而 1-(p^2+(q-p)^2)/q^2=2*p(q-p)/q^2 是掉的概率

    我们设 掉概率分子为A,分母为B    不掉概率分子为C,分母为D

    f[h]= 0     h为奇数

         = C^(h/2-1)*A  /  (B^2)^(h/2-1)*(D^2)

    至于约分只要在一开始把A和B,C和D的约数约掉即可

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<cmath>
      5 #define ll long long
      6 #define mem(a,b) memset(a,b,sizeof(a))
      7 using namespace std;//5137
      8 int maxn(int a,int b){return a>b?a:b;}
      9 int abss(int x){return x<0?-x:x;}
     10 const int Max=50050;
     11 
     12 int prime[100001],num;
     13 bool he[100001];
     14 
     15 __attribute__((optimize("O3"))) void PRIME()
     16 {
     17     int q1=(int)ceil(sqrt(Max));
     18     for(int i=2;i<=Max;++i)
     19     {
     20         if(he[i])continue;
     21         prime[++num]=i;
     22         for(int j=i*2;j<=Max;j+=i)
     23             he[j]=1;
     24     }
     25 }
     26 
     27 
     28 
     29 int p,q,k,m;
     30 int h;
     31 ll a,b;
     32 
     33 __attribute__((optimize("O3"))) ll mi(ll x,ll c)
     34 {
     35     ll ans=1;
     36     while(c)
     37     {
     38         if(c&1)
     39           ans=ans*x%k;
     40         x=x*x%k;
     41         c>>=1;
     42     }
     43     return ans;
     44 }
     45 
     46 int azhi[5201],bzhi[5201];
     47 /*void out11()
     48 {
     49     printf("
    ");
     50     for(int i=1;i<=20;++i)
     51       printf("%d ",azhi[i]);
     52     printf("
    ");
     53     for(int i=1;i<=20;++i)
     54       printf("%d ",bzhi[i]);
     55     printf("
    ");
     56 }*/
     57 __attribute__((optimize("O3"))) void qq()
     58 {
     59     if(h&1||h==0)
     60     {
     61         a=0;
     62         b=0;
     63         return ;
     64     }
     65     mem(azhi,0);
     66     mem(bzhi,0);
     67     int ci=h/2-1;
     68     int q1=2*q*q-2*p*q+p*p;
     69     int q2=2*q*(p-q);
     70     int q3=p;
     71     //printf("ci=%lld q1=%lld q2=%lld q3=%lld
    ",ci,q1,q2,q3);
     72     int maxl=0;
     73     //cout<<1;
     74     int now=0;
     75     while(q2!=1)
     76     {
     77         ++now;
     78         while(!(q2%prime[now]))
     79         {
     80             q2/=prime[now];
     81             ++azhi[now];
     82         }
     83         azhi[now]*=ci;
     84     }
     85     maxl=maxn(maxl,now);
     86     
     87     now=0;
     88     while(q1!=1)
     89     {
     90         ++now;
     91         while(!(q1%prime[now]))
     92         {
     93             q1/=prime[now];
     94             ++azhi[now];
     95         }
     96     }
     97     maxl=maxn(maxl,now);
     98     
     99     now=0;
    100     while(q3!=1)
    101     {
    102         ++now;
    103         while(!(q3%prime[now]))
    104         {
    105             q3/=prime[now];
    106             ++bzhi[now];
    107         }
    108         bzhi[now]*=h;
    109     }
    110     maxl=maxn(maxl,now);
    111     
    112     for(int i=1;i<=maxl;++i)
    113     {
    114         if(azhi[i]>bzhi[i]){azhi[i]-=bzhi[i];bzhi[i]=0;}
    115         else{bzhi[i]-=azhi[i];azhi[i]=0;}
    116     }
    117     //out11();
    118     a=1;b=1;
    119     for(int i=1;i<=maxl;++i)
    120     {
    121         if(azhi[i])
    122           a=(a*(mi(prime[i],azhi[i])%k))%k;
    123         if(bzhi[i])
    124           b=(b*(mi(prime[i],bzhi[i])%k))%k;
    125     }
    126 }
    127 
    128 __attribute__((optimize("O3"))) int main(){
    129     //freopen("1.txt","r",stdin);
    130     //freopen("brtree7.in","r",stdin);
    131     //freopen("brtree.out","w",stdout);
    132     PRIME();
    133     //printf("num=%d
    ",num);
    134     //out11();
    135     scanf("%d%d%d%d",&q,&p,&m,&k);
    136     
    137     while(m--)
    138     {
    139         scanf("%d",&h);
    140         h-=a%k;
    141         qq();
    142         //printf("caocoaca
    ");
    143         printf("%lld %lld
    ",a,b);
    144     }
    145     //printf("
    end
    ");
    146     //while(1);
    147     return 0;
    148 }
    解法1
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cmath>
     5 #define ll long long
     6 #define mem(a,b) memset(a,b,sizeof(a))
     7 using namespace std;
     8 ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
     9 
    10 ll a[1000010],b[1000010];
    11 ll q,p,m,k,h;
    12 
    13 int main(){
    14     //freopen("brtree4.in","r",stdin);
    15     //freopen("2.txt","w",stdout);
    16     scanf("%lld%lld%lld%lld",&p,&q,&m,&k);
    17     //C:fall
    18     ll A=2*p*(q-p),B=q*q,C=2*p*p-2*p*q+q*q,D=q*q;
    19     while(1)
    20     {
    21         ll hh=gcd(A,B);
    22         if(hh==1)break;
    23         A/=hh;B/=hh;
    24     }
    25     while(1)
    26     {
    27         ll hh=gcd(C,D);
    28         if(hh==1)break;
    29         C/=hh;D/=hh;
    30     }
    31     ll nowa=1,nowb=1;
    32     for(int i=2;i<=1000000;i+=2)
    33     {
    34         a[i]=nowa*C%k;
    35         b[i]=nowb*D%k;
    36         nowa=nowa*A%k;
    37         nowb=nowb*B%k;
    38     }
    39     
    40     //printf("%lld %lld
    ",a[1000000],b[1000000]);
    41     
    42     ll aa=0,bb=0;
    43     while(m--)
    44     {
    45         scanf("%lld",&h);
    46         h-=(aa%k);
    47         //printf("h=%d
    ",h);
    48         aa=a[h];bb=b[h];
    49         printf("%lld %lld
    ",aa,bb);
    50     }
    51     //while(1);
    52     return 0;
    53 }
    解法2
  • 相关阅读:
    Day042---浮动 背景图设置 相对定位绝对定位
    day049--jQuery文档操作示例
    iOS 8 Extensions
    《驾驭Core Data》 第三章 数据建模
    《驾驭Core Data》 第二章 Core Data入门
    《驾驭Core Data》 第一章 Core Data概述
    iOS代码工具箱再续
    PS图层混合模式实例详解
    Core Animation编程指南
    iOS应用开发最佳实践系列一:编写高质量的Objective-C代码
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7252354.html
Copyright © 2020-2023  润新知