c 语言知识清单?

Python033

c 语言知识清单?,第1张

1.1 基本数据结构

1. 数组

2. 链表,双向链表

3. 队列,单调队列,双端队列

4. 栈,单调栈

1.2 中级数据结构

1. 堆

2. 并查集与带权并查集

3. hash 表

自然溢出

双hash

1.3 高级数据结构

1. 树状数组

2. 线段树,线段树合并

3. 平衡树

Treap 随机平衡二叉树

Splay 伸展树

* Scapegoat Tree 替罪羊树

4. 块状数组,块状链表

5.* 树套树

线段树套线段树

线段树套平衡树

* 平衡树套线段树

6.可并堆

左偏树

*配对堆

7. *KDtree,*四分树

1.4 可持久化数据结构

1. 可持久化线段树

主席树

2. * 可持久化平衡树

3. * 可持久化块状数组

1.5 字符串相关算法及数据结构

1. KMP

2. AC 自动机

3. 后缀数组

4. *后缀树

5. *后缀自动机

6. 字典树 Trie

7. manacher

1.6 图论相关

1. 最小生成树

prim

kruskal

2. 最短路,次短路,K短路

spfa

dijkstra

floyd

3. 图的连通

连通分量

割点,割边

4. 网络流

最大流

最小割

费用流

分数规划

5. 树相关

树上倍增,公共祖先

树链剖分

树的分治算法(点分治,边分治,*动态?树分治)

动态树 (LCT,*树分块)

虚树

*prufer编码

7. 拓扑排序

8. 欧拉图

9. 二分图

*KM算法

匈牙利算法

1.7 数学相关

1. (扩展)欧几里得算法,筛法,快速幂

斐蜀定理

更相减损术

2. 欧拉函数与*降幂大法

3. 费马小定理

4. 排列组合

lucas定理

5. 乘法逆元

6. 矩阵乘法

7. 数学期望与概率

8. 博弈论

sg函数

树上删边游戏

9. *拉格朗日乘子法

10. 中国剩余定理

11. 线性规划与网络流

12. 单纯型线性规划

13. 辛普森积分

14. 模线性方程组

15. 容斥原理与莫比乌斯反演

16. 置换群

17. 快速傅里叶变换

18. *大步小步法(BSGS),扩展BSGS

1.8 动态规划

1. 一般,背包,状压,区间,环形,树形,数位动态规划

记忆化搜索

斯坦纳树

背包九讲

2. 斜率优化与* 四边形不等式优化

3. 环 + 外向树上的动态规划

4. *插头动态规划

1.9 计算几何

1. 计算几何基础

2. 三维计算几何初步

3. *梯形剖分与*三角形剖分

4. 旋转卡壳

5. 半平面交

6. pick定理

7. 扫描线

1.10 搜索相关

1. bfs,dfs

2. A* 算法

3. 迭代加深搜索,双向广搜

1.11 特殊算法

1. 莫队算法,*树上莫队

2. 模拟退火

3. 爬山算法

4. 随机增量法

1.12 其它重要工具与方法

1.模拟与贪心

2. 二分,三分法(求偏导)

3. 分治,CDQ分治

4. 高精度

5. 离线

6. ST表

1.13 STL

1. map

2. priority_queue

3. set

4. bitset

5. rope

1.14 非常见算法

1. *朱刘算法

2. *弦图与区间图

其实以上的算法能学完1/3就已经很好了

望采纳,谢谢

#include<iostream>

#include<iomanip>

using namespace std

int main()

{

    int p[100][100]

    int i,j,k

    for(i=1i<5i++)

    {

        p[i][0]=0

        p[i][i+1]=0

    }

    p[1][1]=1

 

    for(i=2i<=5i++)

    {  

        k=1

        for(j=ik<=jk++)

        {  

            p[i][k]=p[i-1][k-1]+p[i-1][k]

        }

 

    }    

    for(i=1i<=5i++)

    {

        k=1

        for(k<=ik++){

            if(k==1)cout<<setw(7-i)<<p[i][k]

            if(k!=1)cout<<setw(2)<<p[i][k]

            if(k%i==0)cout<<endl

        }

    }

    getchar()

    return 0

}

RSA算法它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字

命名:Ron Rivest, Adi Shamir 和Leonard

Adleman。但RSA的安全性一直未能得到理论上的证明。它经历了各种攻击,至今未被完全攻破。

一、RSA算法 :

首先, 找出三个数, p, q, r,

其中 p, q 是两个相异的质数, r 是与 (p-1)(q-1) 互质的数

p, q, r 这三个数便是 private key

接著, 找出 m, 使得 rm == 1 mod (p-1)(q-1)

这个 m 一定存在, 因为 r 与 (p-1)(q-1) 互质, 用辗转相除法就可以得到了

再来, 计算 n = pq

m, n 这两个数便是 public key

编码过程是, 若资料为 a, 将其看成是一个大整数, 假设 a <n

如果 a >= n 的话, 就将 a 表成 s 进位 (s <= n, 通常取 s = 2^t),

则每一位数均小於 n, 然後分段编码

接下来, 计算 b == a^m mod n, (0 <= b <n),

b 就是编码後的资料

解码的过程是, 计算 c == b^r mod pq (0 <= c <pq),

於是乎, 解码完毕 等会会证明 c 和 a 其实是相等的 :)

如果第三者进行窃听时, 他会得到几个数: m, n(=pq), b

他如果要解码的话, 必须想办法得到 r

所以, 他必须先对 n 作质因数分解

要防止他分解, 最有效的方法是找两个非常的大质数 p, q,

使第三者作因数分解时发生困难

<定理>

若 p, q 是相异质数, rm == 1 mod (p-1)(q-1),

a 是任意一个正整数, b == a^m mod pq, c == b^r mod pq,

则 c == a mod pq

证明的过程, 会用到费马小定理, 叙述如下:

m 是任一质数, n 是任一整数, 则 n^m == n mod m

(换另一句话说, 如果 n 和 m 互质, 则 n^(m-1) == 1 mod m)

运用一些基本的群论的知识, 就可以很容易地证出费马小定理的

<证明>

因为 rm == 1 mod (p-1)(q-1), 所以 rm = k(p-1)(q-1) + 1, 其中 k 是整数

因为在 modulo 中是 preserve 乘法的

(x == y mod z and u == v mod z => xu == yv mod z),

所以, c == b^r == (a^m)^r == a^(rm) == a^(k(p-1)(q-1)+1) mod pq

1. 如果 a 不是 p 的倍数, 也不是 q 的倍数时,

则 a^(p-1) == 1 mod p (费马小定理) => a^(k(p-1)(q-1)) == 1 mod p

a^(q-1) == 1 mod q (费马小定理) => a^(k(p-1)(q-1)) == 1 mod q

所以 p, q 均能整除 a^(k(p-1)(q-1)) - 1 => pq | a^(k(p-1)(q-1)) - 1

即 a^(k(p-1)(q-1)) == 1 mod pq

=> c == a^(k(p-1)(q-1)+1) == a mod pq

2. 如果 a 是 p 的倍数, 但不是 q 的倍数时,

则 a^(q-1) == 1 mod q (费马小定理)

=> a^(k(p-1)(q-1)) == 1 mod q

=> c == a^(k(p-1)(q-1)+1) == a mod q

=> q | c - a

因 p | a

=> c == a^(k(p-1)(q-1)+1) == 0 mod p

=> p | c - a

所以, pq | c - a => c == a mod pq

3. 如果 a 是 q 的倍数, 但不是 p 的倍数时, 证明同上

4. 如果 a 同时是 p 和 q 的倍数时,

则 pq | a

=> c == a^(k(p-1)(q-1)+1) == 0 mod pq

=> pq | c - a

=> c == a mod pq

Q.E.D.

这个定理说明 a 经过编码为 b 再经过解码为 c 时, a == c mod n (n = pq)

但我们在做编码解码时, 限制 0 <= a <n, 0 <= c <n,

所以这就是说 a 等於 c, 所以这个过程确实能做到编码解码的功能

二、RSA 的安全性

RSA的安全性依赖于大数分解,但是否等同于大数分解一直未能得到理论上的证明,因为没有证明破解

RSA就一定需要作大数分解。假设存在一种无须分解大数的算法,那它肯定可以修改成为大数分解算法。目前, RSA

的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显然的攻击方法。现在,人们已能分解多个十进制位的大素数。因此,模数n

必须选大一些,因具体适用情况而定。

三、RSA的速度

由于进行的都是大数计算,使得RSA最快的情况也比DES慢上倍,无论是软件还是硬件实现。速度一直是RSA的缺陷。一般来说只用于少量数据加密。

四、RSA的选择密文攻击

RSA在选择密文攻击面前很脆弱。一般攻击者是将某一信息作一下伪装( Blind),让拥有私钥的实体签署。然后,经过计算就可得到它所想要的信息。实际上,攻击利用的都是同一个弱点,即存在这样一个事实:乘幂保留了输入的乘法结构:

( XM )^d = X^d *M^d mod n

前面已经提到,这个固有的问题来自于公钥密码系统的最有用的特征--每个人都能使用公钥。但从算法上无法解决这一问题,主要措施有两条:一条是采用好的公

钥协议,保证工作过程中实体不对其他实体任意产生的信息解密,不对自己一无所知的信息签名;另一条是决不对陌生人送来的随机文档签名,签名时首先使用

One-Way HashFunction 对文档作HASH处理,或同时使用不同的签名算法。在中提到了几种不同类型的攻击方法。

五、RSA的公共模数攻击

若系统中共有一个模数,只是不同的人拥有不同的e和d,系统将是危险的。最普遍的情况是同一信息用不同的公钥加密,这些公钥共模而且互质,那末该信息无需私钥就可得到恢复。设P为信息明文,两个加密密钥为e1和e2,公共模数是n,则:

C1 = P^e1 mod n

C2 = P^e2 mod n

密码分析者知道n、e1、e2、C1和C2,就能得到P。

因为e1和e2互质,故用Euclidean算法能找到r和s,满足:

r * e1 + s * e2 = 1

假设r为负数,需再用Euclidean算法计算C1^(-1),则

( C1^(-1) )^(-r) * C2^s = P mod n

另外,还有其它几种利用公共模数攻击的方法。总之,如果知道给定模数的一对e和d,一是有利于攻击者分解模数,一是有利于攻击者计算出其它成对的e’和d’,而无需分解模数。解决办法只有一个,那就是不要共享模数n。

RSA的小指数攻击。 有一种提高 RSA速度的建议是使公钥e取较小的值,这样会使加密变得易于实现,速度有

所提高。但这样作是不安全的,对付办法就是e和d都取较大的值。

RSA算法是

第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人

们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。即RSA

的重大缺陷是无法从理论上把握它的保密性能

如何,而且密码学界多数人士倾向于因子分解不是NPC问题。

RSA的缺点主要有:A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。B)分组长度太大,为保证安全性,n 至少也要 600

bits

以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。目

前,SET( Secure Electronic Transaction )协议中要求CA采用比特长的密钥,其他实体使用比特的密钥。

C语言实现

#include <stdio.h>

int candp(int a,int b,int c)

{ int r=1

b=b+1

while(b!=1)

{

r=r*a

r=r%c

b--

}

printf("%d\n",r)

return r

}

void main()

{

int p,q,e,d,m,n,t,c,r

char s

printf("please input the p,q: ")

scanf("%d%d",&p,&q)

n=p*q

printf("the n is %3d\n",n)

t=(p-1)*(q-1)

printf("the t is %3d\n",t)

printf("please input the e: ")

scanf("%d",&e)

if(e<1||e>t)

{

printf("e is error,please input again: ")

scanf("%d",&e)

}

d=1

while(((e*d)%t)!=1) d++

printf("then caculate out that the d is %d\n",d)

printf("the cipher please input 1\n")

printf("the plain please input 2\n")

scanf("%d",&r)

switch(r)

{

case 1: printf("input the m: ")/*输入要加密的明文数字*/

scanf("%d",&m)

c=candp(m,e,n)

printf("the cipher is %d\n",c)break

case 2: printf("input the c: ")/*输入要解密的密文数字*/

scanf("%d",&c)

m=candp(c,d,n)

printf("the cipher is %d\n",m)break

}

getch()

}