zoukankan      html  css  js  c++  java
  • LightOj 1170

    题目链接:

      http://www.lightoj.com/volume_showproblem.php?problem=1170

    题目描述:
      给出一些满足完美性质的一列数(x > 1 and y > 1 such that m = xy.) 然后给出一个区间,问在这个区间中的完美数组成的搜索二叉树的个数是多少?
    解题思路:

      1,打标算出所有的完美数列中的数字

      2,打表算出卡特兰数列,等着以后用

      3,卡特兰数列递推式:F[N] = F[N-1] * ( 4 * N - 2 ) / ( N + 1 ), 求余的时候牵涉到逆元,用扩展欧几里德或者费马小定理求解逆元

    准备到这里就万事大吉了!

        卡特兰数应用

    代码:

      

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 
     8 #define LL long long
     9 #define maxn 110100
    10 #define mod 100000007
    11 const LL Max = 1e10;
    12 LL a[maxn], ans[maxn], num;
    13 
    14 LL Extended_Euclid (LL a, LL b, LL &x, LL &y)
    15 {
    16     //处理 a * b > 0 的情况
    17     if (b == 0)
    18     {
    19         x = 1;
    20         y = 0;
    21         return a;
    22     }
    23 
    24     LL r = Extended_Euclid (b, a%b, x, y), t;
    25     t = x;
    26     x = y;
    27     y = t - a / b * y;
    28     return r;
    29 }
    30 
    31 void init ()
    32 {
    33     //memset (vis, 0, sizeof(vis));
    34     num = 0;
    35     for (LL i=2; i<maxn; i++)
    36     {
    37         LL j = i * i;
    38         while (j <= Max)
    39         {
    40             a[num ++] = j;
    41             j *= i;
    42         }
    43     }
    44 
    45     sort (a, a+ num);
    46     num = unique (a, a+num) - a;
    47 
    48     ans[0] = 0;
    49     ans[1] = 1;
    50     for (LL i=2; i<maxn; i++)
    51     {
    52         /// F[N] = F[N-1] * ( 4 * N - 2 ) / ( N + 1 )
    53         LL x, y, r;
    54         r = Extended_Euclid (i+1, mod, x, y);
    55         ans[i] = ans[i-1] * (4 * i - 2) % mod * (x % mod + mod ) % mod;
    56     }
    57 }
    58 
    59 int main ()
    60 {
    61     init ();
    62 
    63     int T, L = 1;
    64     cin >> T;
    65     while (T --)
    66     {
    67         LL x, y;
    68         scanf ("%lld %lld", &x, &y);
    69         x = lower_bound (a, a+num, x) - a;
    70         y = upper_bound (a, a+num, y) - a;
    71 
    72         printf ("Case %d: %lld
    ", L++, ans[y - x]);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    集合(二)
    集合(一)
    面向对象(三)
    面向对象(二)
    面向对象(一)
    关键字
    java基础
    android开发_LogCat的使用
    linux基础之CentOS7新特性
    shell编程(二)之算术运算
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/5414079.html
Copyright © 2011-2022 走看看