吉林省冬令营DAY4知识梳理与总结

DAY4讲的是数论基础,学到了很多东西,做一下便于自己理解的整理

  • 快速幂

要求一个数 abmodP

考虑ab,把b按二进制分解

例如:

         59

       (9)10=(1001) 2 =1*23+0*22+0*21+1*20

   那么我们可以把b的所有为1的二进制位对应的次幂相乘得到ab

    59= 51*58

代码如下

 1 int pw(int a,int b)
 2 {
 3     int r=1;
 4     while(b)
 5     {
 6         if(b&1) r=r*a;
 7         a*=a;
 8         b>>=1;
 9     }
10     return r;
快速幂

 

  • 线性同余方程

  形如 a*x≡b(mod p),求x的值

    一些性质:

                 1.如果gcd(a,p)=1,则方程有且仅有一个解 x=a-1b

  2.方程有解⇔ gcd(𝑎,𝑝)|b,且解数为gcd(𝑎,𝑝)

   同余方程与不等式a*x=p*y+b同解

   例如:  51*x≡4(mod 50)

             x=(1/51)*4

            52*x≡4(mod12)

             x=gcd(52,12)  x=4 

  • 费马小定理

ap≡a(mod p)

条件:p为质数并且a不是p的倍数。特别的a可以等于0。

推论:ap-1≡1(mod p)

  • 欧拉函数

暂时不怎么懂

  • 欧拉定理

暂时不怎么懂

 

  •   乘法逆元

我们知道,乘法是除法的逆运算也就是说a*(1/a)=1

由欧拉定理 a*aφ(p)-11/a表示为a-1

条件是a和p互质。

而一般p都给的是一个特别大的素数,所以可以用到欧拉函数的公式:φ(x)=x-1.

所以我们可以得到乘法逆元:ap-2

  • 扩展欧几里得算法

   :在求出gcd(a,b)时还可已顺带解出不定方程 a*x+b*y=gcd(a,b)的一组解

   此方程等价于同余方程a*x≡gcd(a,b)(mod b)

     x=gcd(a,b)

  还不算太懂。。。。。

  • 排列组合

例子:n个人排成一排方案数:n!=1*2*......*n

从n个人选出k个人的方案数:

  n!/k!*(n-k)!

这就是组合数 可以记作Ck或者是 ( kn)。

杨辉三角形递推式

C(n,k)=C(n-1,k-1)+C(n-1,k).

  • 朴素筛法

由2-sqrt(n)的算法判断n是否为素数效率太低了。根据一个合数必然是两个素数的倍数,所以,我们可以先建立一个数组,开始的时候全部标记为false,从2开始,当碰到一个数为false的时候,开始循环,把它的倍数都标记为true,表示不是素数。这样当我们在判断非常大范围的素数的时候就可以用较小的时间求出来。

 

   嗯,今天讲的东西差不多就是这些了, 总体来说听的半懂不懂,回到家自己仔细的想一想,查一些资料,大约能懂的也都懂了,不懂的相信以后慢慢理解也会懂的。

  

 下午的测试

 

 代码如下:

 1 #include <cstdio>
 2 using namespace std;
 3 #define mod 1000000007
 4 typedef long long ll;
 5 ll  a[1000008],b[1000007];
 6 int pw(ll a,ll b)
 7 {
 8     ll  r=1;
 9     while(b)
10     {
11         if(b&1) r=(r*a)%mod;
12         a=(a*a)%mod;
13         b>>=1;
14     }
15     return r;
16 }
17 int main()
18 {
19 //    freopen("ball.in","r",stdin);
20 //    freopen("ball.out","w",stdout);
21     int N,M,K;
22     scanf("%d%d%d",&N,&M,&K);
23     int n=N-K;
24     int m=M-1;
25     a[0]=1;
26     for(int i=1;i<=n;i++) a[i]=(a[i-1]*i)%mod;
27     b[n]=pw(a[n],mod-2);
28     for(int i=n-1;i>=0;i--) b[i]=(b[i+1]*(i+1))%mod;
29     int ans=(((a[n]*b[m])%mod)*b[n-m])%mod;
30     printf("%d",ans);
31     return 0;
32 }
T1代码

分析:预处理阶乘和逆元,因为最小为K所以n=N-K,m=M-1。接下来往里套排列组合C(n,m)就可以算出结果了。

反思:当天考试的时候很多知识点不会,暴力拿了一些分,回到家后仔细思考了下,大致的明白了知识点。有收获就好。

 

   代码如下:

  

posted @ 2017-01-17 20:03  lxzyzby  阅读(312)  评论(0)    收藏  举报