首页 > 代码库 > 黑红树题解

黑红树题解

这个题应该是今天考试中最水的一个题了,考试的时候第四题费太多时间了,这个题几乎没打,很郁闷。无奈。。。。。。。。

solution:

  把树分成两层两层考虑,那么下面的一层显然不可能出现结束的状态,因为取到红和黑的点数之差一定为1。每一层只有三种情况:1红1黑,0红2黑,2红0黑。因为达到这一层的时候一定取到红点的个数和取到黑点的个数之和一定是偶数,因此红点和黑点的个数一定相等。当取到0红2黑和2红0黑的时候在这一层就结束了,否则1红1黑就走到下一层。结束的概率是p^2/q^2+(p-q)^2/q^2,不结束的概率是1-‘上面那式子’。令能结束的概率是A/B,一轮不能结束的概率是C/D。那么答案就是[(C/D)^(t-1)] * (A/B)。因为还要约分,考虑到对于n<=10000,2的因子最多不会超过20个,所以前20个直接用分解质因数搞一下就好,后面直接乘起来;

其实就是把公式推出来,一且解决,不过记得每次深度除以e2,因为把两个分为了一部份。

记得开long long

如果有问题欢迎各位大神指出

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 long long read() {
 6     long long s=0,f=1;
 7     char ch=getchar();
 8     while(ch>9||ch<0) {
 9         if(ch==-)
10             f=-1;
11         ch=getchar();
12     }
13     while(ch>=0&&ch<=9) {
14         s=(s<<1)+(s<<3)+(ch^48);
15         ch=getchar();
16     }
17     return s*f;
18 }
19 long long p,q,T,k;
20 long long gcd(long long x,long long y) {
21     return y==0?x:gcd(y,x%y);
22 }
23 long long ansa,ansb,pi[500005],qi[500005];
24 int main() {
25     p=read();
26     q=read();
27     T=read();
28     k=read();
29     long long qq=q*q,pp=q*q-p*p-(q-p)*(q-p);
30     long long ff=gcd(qq,pp);
31     qq/=ff;
32     pp/=ff;
33     pi[0]=qi[0]=1;
34     for(int i=1; i<=500000; i++) {
35         pi[i]=(pi[i-1]*pp)%k;
36         qi[i]=(qi[i-1]*qq)%k;
37     }
38     long long d1=2*p*p-2*p*q+q*q,d2=q*q;
39     ff=gcd(d1,d2);
40     d1/=ff;
41     d2/=ff;
42     while(T--) {
43         long long h=read();
44         h-=ansa;
45         if(h&1||!h) {
46             ansa=ansb=0;
47             printf("0 0\n");
48             continue;
49         }
50         h/=2;
51         ansa=(pi[h-1]*d1)%k;
52         ansb=(qi[h-1]*d2)%k;
53         printf("%lld %lld\n",ansa,ansb);
54     }
55     return 0;
56 }
View Code

 

黑红树题解