首页 > 其他 > 详细

卡特兰数&&prufer序列&&BSGS水题集

时间:2019-07-21 23:18:33      阅读:101      评论:0      收藏:0      [点我收藏+]

首先说一下BSGS的一个坑点:

解方程A^x≡B(mod p)

需要特判一个东西=>A%p==B%p==0?

如果相等的话puts("1")反之则无解。

因为如果A%p=0,那么无法移项,导致BSGS算法的错误

进入正题:

一   卡特拉数(C(2*n,n)/(n+1))用于处理01序列里任意位置0的个数>1的情况。。

但知道定义没用,重要的是打表找规律。

善于用next_permutation,搜索等工具找出前几项。

记住卡特兰数的前几项:1 2 5 14 42 132 429。(反正也只能求出这几项)

至于求法,先化到最简,取模可以用lucas,不取模的高精。

喜欢高精除的畜生就打高精除,不喜欢的就分解质因数,数据小的也可以O(n^2)枚举。

贴一下分解质因数的代码:

技术分享图片
 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 #define MAXN 4000005
 5 int prime[MAXN],tot,n,frpr[MAXN],fenzi[MAXN],tot1;
 6 void pre()
 7 {
 8     for(int i=2;i<=2*n;i++)
 9     {
10         if(!frpr[i])
11         {
12             frpr[i]=i;
13             prime[++tot]=i;
14         }
15         for(int j=1;j<=tot;j++)
16         {
17             if(prime[j]*i>2*n)break;
18             frpr[prime[j]*i]=prime[j];
19             if(!(i%prime[j]))break;
20         }
21     }
22     return ;
23 }
24 void Get_pr(int x,int opt)
25 {
26     while(x!=1)
27     {
28         if(opt==0)fenzi[frpr[x]]++;
29         else fenzi[frpr[x]]--;
30         x/=frpr[x];
31     }
32     return ;
33 }
34 int main()
35 {
36     int p,ans=1;
37     scanf("%d%d",&n,&p);
38     pre();
39     for(int i=n+2;i<=2*n;i++)Get_pr(i,0);
40     for(int i=1;i<=n;i++)Get_pr(i,1);
41     for(int i=1;i<=tot;i++)
42     {
43         while(fenzi[prime[i]]>0)
44         {
45             ans=1ll*ans*prime[i]%p;
46             fenzi[prime[i]]--;
47         }
48     }
49     cout<<ans<<endl;
50     return 0;
51 }
View Code

二  prufer序列

用n-2个点表示n个节点的有标号树,可以证明prufer序列和对应的树都是唯一确定的。

由此可以得到一些推理:

1. n个点构成的无根树的个数:n^(n-2)

2. 确定n个点度数分别为d1,d2…时无根树个数: (n-2)!/((d1-1)!*(d2-1)!*…)

3.  n个点的有标号有根树的个数: n*n^(n-2)=n^(n-1)

4. 所有节点的度之和为n*2-2

除了统计树的个数,别的。。。就没啥了(听说还能优化暴力枚举)

 

卡特兰数&&prufer序列&&BSGS水题集

原文:https://www.cnblogs.com/hzoi-kx/p/11222748.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!