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


    首先说一下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

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

     三 BSGS

    模板:

     1 void insert(int x,int d)
     2 {
     3     int k=x%mod;
     4     val[++cnt]=x;nxt[cnt]=head[k];id[cnt]=d;head[k]=cnt;
     5 }
     6 int find(int x)
     7 {
     8     int k=x%mod;
     9     for(int i=head[k];i;i=nxt[i])
    10         if(val[i]==x)return id[i];
    11     return -2333;
    12 }
    13 int BSGS()
    14 {
    15     int m=ceil(sqrt(p*1.0)),bs=1;
    16     int now=1;insert(B%p,0);//insert A^j*B
    17     if(B==1)return 0;
    18     for(int i=1;i<m;i++)
    19     {
    20         now=1ll*now*A%p;
    21         insert(1ll*now*B%p,i);
    22     }
    23     now=1ll*now*A%p;
    24     for(int i=m;;i+=m)
    25     {
    26         bs=1ll*bs*now%p;
    27         int x=find(bs);
    28         if(x!=-2333)return i-x;
    29         if(i>p)break;
    30     }
    31     return -2333;
    32 }
    View Code

    除了上面提到的坑点,还有就是根据题意啦

  • 相关阅读:
    按钮UIButton内图片和文字位置的设置(两种方式)
    关于Xcode上的Other linker flags基本介绍
    GCD定时器
    线程间的通信(3种方式)
    scrollView中内部控件的悬停
    十七:字符串文件的读写
    十六:NSString的创建以及相关细节
    十五:NSValue
    react生命周期遇到的问题
    笔记----深入浅出《React和Redux》第四章
  • 原文地址:https://www.cnblogs.com/hzoi-kx/p/11222748.html
Copyright © 2020-2023  润新知