├── 算法学习 ├── ML │ └── README.md ├── Binary Tree │ ├── 4-字典树Trie │ │ └── README.md │ ├── 2-二叉查找树 │ │ └── BiSearchTree │ │ │ ├── README.md │ │ │ ├── bisearch │ │ │ └── bisearchtree.h │ ├── 3-平衡树AVL │ │ └── README.md │ ├── 后缀树.md │ ├── 伸展树.md │ ├── README.md │ ├── B树.md │ ├── 8-二叉堆(优先队列) │ │ └── heap.c │ └── 赫夫曼编码.md ├── Big Data │ ├── simhash算法.md │ ├── btree_insert.gif │ ├── disk_search.png │ ├── 倒排索引(Inverted Index).md │ ├── Hash映射,分而治之.md │ ├── Bitmap.md │ ├── 双层桶划分.md │ ├── 分布处理之Mapreduce.md │ ├── README.md │ └── 外排序.md ├── Algorithms Job Interview │ ├── 测试代码 │ │ ├── c13-1.c │ │ ├── 4-1.c │ │ ├── c7.c │ │ ├── c20.c │ │ ├── c10.c │ │ ├── c9.c │ │ ├── 22.c │ │ ├── 7.c │ │ ├── 8.c │ │ ├── 24.c │ │ ├── 28.c │ │ ├── 23.c │ │ ├── 5.c │ │ ├── 21.c │ │ ├── c18.c │ │ ├── c12.c │ │ ├── c13-2.c │ │ ├── 20.c │ │ ├── c11.c │ │ ├── 26.c │ │ ├── c15.c │ │ ├── c3.c │ │ ├── c5.c │ │ ├── c11-2.c │ │ ├── bt1.c │ │ ├── c8.c │ │ ├── 25.c │ │ ├── c14.c │ │ ├── one_appear_count_by_binary.c │ │ ├── c4.c │ │ ├── 2.c │ │ ├── 27.c │ │ ├── c1.c │ │ ├── c6.c │ │ ├── c17.c │ │ ├── c19.c │ │ ├── delete_occurence_character.c │ │ ├── Power.c │ │ ├── char_first_appear_once.c │ │ ├── replce_blank.c │ │ ├── 11.c │ │ ├── 10.c │ │ ├── proc.c │ │ ├── 12.c │ │ ├── c16.c │ │ ├── 9.c │ │ ├── fibonacci.c │ │ ├── 1.c │ │ ├── c2.c │ │ ├── print_matrix.c │ │ ├── longest_continuious_number.c │ │ └── revert_by_word.c │ ├── 九度OJ.md │ ├── leetcode.md │ ├── 图.md │ ├── 系统设计.md │ ├── README.md │ └── 编程之美 │ │ └── README.md ├── .DS_Store ├── Sort │ ├── qsort.gif │ ├── heapsort.gif │ ├── bubblesort.gif │ ├── mergesort.gif │ ├── selectsort.gif │ ├── shellsort.gif │ └── 8.c ├── images │ ├── fast-sort.gif │ ├── heap-sort.gif │ ├── bubble-sort.gif │ ├── merge-sort.gif │ ├── select-sort.gif │ └── shell-sort.gif ├── Hash Table │ └── hashmap.png ├── Algorithms Analysis │ ├── 贪心算法.md │ ├── 迭代法.md │ ├── 穷举搜索法.md │ ├── 分治算法.md │ ├── README.md │ ├── 动态规划.md │ ├── 回溯法.md │ └── 递归.md ├── Graph Algorithms │ └── README.md ├── String │ └── README.md ├── 15 Classic Algorithms │ └── README.md ├── Link Table │ └── README.md ├── Algorithms In DB │ └── README.md ├── Search Algorithms │ └── README.md └── Algorithms In Open Source │ ├── README.md │ └── YYCache.md ├── 算法例题 ├── [提高训练]图论之最短路径 │ └── phoneline.cpp ├── .DS_Store ├── [基本算法]递推 │ ├── flag.png │ ├── cover.md │ ├── flag.cpp │ ├── cover.cpp │ ├── flag.md │ ├── marathon.md │ └── marathon.cpp ├── [csp-jx2019] │ ├── P5689多叉堆.cpp │ ├── P5690日期.cpp │ └── P5686和积和.cpp ├── [基本算法]分治和递归 │ ├── car.md │ └── car.cpp ├── [c++基础]函数的递归调用和应用举例 │ ├── tower.cpp │ ├── ratf.cpp │ ├── number.cpp │ └── twopower.cpp ├── [基本算法]穷举 │ ├── triangle.cpp │ ├── coin.cpp │ ├── ratio.cpp │ ├── comb1.cpp │ ├── comb.cpp │ ├── cow.cpp │ └── matches.cpp ├── [基本算法]阶段测试一 │ ├── set.md │ ├── count.cpp │ ├── set.cpp │ ├── bishop.cpp │ └── whatbase.cpp ├── [基本算法]贪心 │ ├── delete.cpp │ ├── kaj.md │ ├── max.cpp │ ├── kaj.cpp │ ├── water.cpp │ └── match.cpp ├── [基本算法]宽度优先搜索 │ ├── area.md │ └── area.cpp ├── [c++基础]一维数组的统计查找和排序 │ ├── height2.md │ ├── paiming.md │ ├── count.cpp │ ├── count.md │ ├── paiming.cpp │ ├── paiming1.cpp │ └── height2.cpp ├── [洛谷题单]动态规划之动态规划的引入 │ ├── P1216.cpp │ └── P1434.cpp ├── [洛谷题单]动态规划之线性状态动态规划 │ ├── P1439.cpp │ ├── p1439_1.cpp │ ├── P1020_1.cpp │ ├── P5858.cpp │ ├── P1280.cpp │ ├── P1020.cpp │ ├── p4933_1.cpp │ └── P5858_1.cpp ├── [基本算法]动态规划 │ ├── lcs.cpp │ ├── flower.cpp │ ├── digtriangle.cpp │ ├── missile1.cpp │ ├── book.cpp │ ├── chorus.cpp │ ├── missile.cpp │ └── getnum.cpp ├── [c++基础]二维数组的定义操作和数字方阵 │ ├── carpet.cpp │ ├── magic.cpp │ ├── square2.cpp │ └── snake2.cpp ├── [基本算法]深度优先搜索 │ ├── volume.cpp │ ├── decompose.cpp │ ├── ticket.cpp │ └── meeting.cpp ├── [CSP-S2019] │ ├── P5665-划分.cpp │ └── P5657-格雷码.cpp ├── [洛谷题单]线段树与树状数组 │ └── P3373.cpp ├── [洛谷题单]动态规划之区间与环形动态规划 │ ├── CF607B.cpp │ ├── P4170.cpp │ └── P1220.cpp ├── [c++基础]指针与链表 │ ├── monkey.cpp │ └── flag.cpp ├── [洛谷2020十月赛] │ ├── P6858_1.cpp │ └── P6858.cpp ├── [基本算法]回溯法 │ ├── book.cpp │ └── mas.cpp ├── [提高训练]动态规划之树型DP │ ├── choose.cpp │ ├── strategi.cpp │ ├── aniv.cpp │ ├── TREE.cpp │ ├── transfer.cpp │ ├── apple.cpp │ └── leaf.cpp ├── [提高训练]动态规划之区间DP │ ├── energy.cpp │ ├── kh.cpp │ └── separation.cpp ├── [洛谷题单]二叉堆与ST表 │ ├── P3865.cpp │ ├── P1631.cpp │ ├── P1168.cpp │ ├── P4053.cpp │ └── P1801.cpp ├── [基本数据结构]栈及栈的应用 │ └── expr.cpp ├── [洛谷题单]动态规划之树与图上的动态规划 │ └── P1613.cpp ├── [洛谷题库] │ ├── p2052.cpp │ ├── P5888.cpp │ └── P2886.cpp ├── [提高训练]动态规划之数位DP │ ├── test.cpp │ ├── none62.cpp │ └── test2.cpp ├── [洛谷题单]搜索剪枝策略 │ └── P4799.cpp ├── [洛谷题单]动态规划之状态压缩动态规划 │ ├── P1879.cpp │ └── P1896.cpp ├── [洛谷题单]图论之最短路径 │ ├── P1119.cpp │ └── P4779.cpp ├── [基本数据结构]并查集及其应用 │ └── relation.cpp ├── [洛谷题单]图论之基础树上问题 │ ├── P3379.cpp │ └── P1395.cpp ├── [提高训练]动态规划之状压DP │ ├── zoo.cpp │ └── cowfood.cpp ├── [c++基础]结构体的定义和应用 │ └── birthday.cpp └── [洛谷提高历练地] │ └── [搜索] │ ├── P1120-小木棍.cpp │ └── P1441-fama.cpp ├── .DS_Store └── 算法模版 ├── .DS_Store ├── MT ├── gcd-lcm.cpp ├── inv-fermat.cpp ├── nim.cpp ├── inv-linear.cpp ├── Bézout’s-theorem.cpp ├── inv-exgcd.cpp ├── quick-pow.cpp ├── euler-prime.cpp ├── crt.cpp ├── lucas.cpp ├── miller-rabin.cpp └── quick-matrix-pow.cpp ├── DP ├── lis-greedy.cpp ├── knapsack-pure.cpp ├── knapsack-complete.cpp ├── lcs-lis.cpp ├── knapsack-grouped.cpp ├── lcs-normal.cpp ├── lcis.cpp ├── lis-bit.cpp ├── knapsack-multiple.cpp └── digit.cpp ├── AL ├── cantor-expansion.cpp ├── discretization.cpp ├── three-divide.cpp └── radix-sort.cpp ├── DS ├── linear-basis.cpp ├── sparse-table.cpp ├── normal-bit.cpp ├── disjoint-set.cpp ├── humdrum-queue.cpp └── dynamic-sgt.cpp ├── SA ├── manacher.cpp ├── kmp.cpp └── ac-automaton.cpp └── GT ├── kruskal.cpp └── spfa.cpp /算法学习/ML/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /算法例题/[提高训练]图论之最短路径/phoneline.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /算法学习/Binary Tree/4-字典树Trie/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /算法学习/Big Data/simhash算法.md: -------------------------------------------------------------------------------- 1 | 2 | ## simhash算法 3 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c13-1.c: -------------------------------------------------------------------------------- 1 | int arr[80]; -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/.DS_Store -------------------------------------------------------------------------------- /算法例题/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法例题/.DS_Store -------------------------------------------------------------------------------- /算法学习/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/.DS_Store -------------------------------------------------------------------------------- /算法模版/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法模版/.DS_Store -------------------------------------------------------------------------------- /算法学习/Sort/qsort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Sort/qsort.gif -------------------------------------------------------------------------------- /算法例题/[基本算法]递推/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法例题/[基本算法]递推/flag.png -------------------------------------------------------------------------------- /算法学习/Binary Tree/2-二叉查找树/BiSearchTree/README.md: -------------------------------------------------------------------------------- 1 | 2 | ###环境 3 | 4 | 5 | ###编译 6 | 7 | 8 | -------------------------------------------------------------------------------- /算法学习/Sort/heapsort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Sort/heapsort.gif -------------------------------------------------------------------------------- /算法学习/Sort/bubblesort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Sort/bubblesort.gif -------------------------------------------------------------------------------- /算法学习/Sort/mergesort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Sort/mergesort.gif -------------------------------------------------------------------------------- /算法学习/Sort/selectsort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Sort/selectsort.gif -------------------------------------------------------------------------------- /算法学习/Sort/shellsort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Sort/shellsort.gif -------------------------------------------------------------------------------- /算法学习/images/fast-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/images/fast-sort.gif -------------------------------------------------------------------------------- /算法学习/images/heap-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/images/heap-sort.gif -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/九度OJ.md: -------------------------------------------------------------------------------- 1 | 2 | 题目来自 [九度OJ](http://ac.jobdu.com/index.php) 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /算法学习/Hash Table/hashmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Hash Table/hashmap.png -------------------------------------------------------------------------------- /算法学习/images/bubble-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/images/bubble-sort.gif -------------------------------------------------------------------------------- /算法学习/images/merge-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/images/merge-sort.gif -------------------------------------------------------------------------------- /算法学习/images/select-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/images/select-sort.gif -------------------------------------------------------------------------------- /算法学习/images/shell-sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/images/shell-sort.gif -------------------------------------------------------------------------------- /算法学习/Big Data/btree_insert.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Big Data/btree_insert.gif -------------------------------------------------------------------------------- /算法学习/Big Data/disk_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Big Data/disk_search.png -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/4-1.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | 3 | int main(){ 4 | 5 | printf("%ld",236432123443*33453098); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /算法学习/Binary Tree/2-二叉查找树/BiSearchTree/bisearch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ColdeZhang/Note_of_IOI/HEAD/算法学习/Binary Tree/2-二叉查找树/BiSearchTree/bisearch -------------------------------------------------------------------------------- /算法学习/Binary Tree/3-平衡树AVL/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### AVL 实现过程中的问题 3 | 4 | 5 | 6 | ### AVL 实际使用案例 7 | 8 | * LLVM 的 ImmutableSet,其底层的实现选择为 AVL 树 9 | * 《一种基于二叉平衡树的P2P覆盖网络的研究》论文 -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c7.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int* p; 5 | p = (int*)malloc(sizeof(int)); 6 | *p = 10; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Analysis/贪心算法.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 贪心算法 4 | 5 | 不追求最优解,只找到满意解。 6 | 7 | 8 | #### 赫夫曼编码 9 | 10 | 11 | 12 | #### 其它案例 13 | 14 | 找回零钱问题 15 | 装箱问题 16 | 17 | 18 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c20.c: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | char ch1; 4 | char ch2; 5 | ch1 = getchar(); 6 | ch2 = getchar(); 7 | printf("%d %d", ch1, ch2); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Analysis/迭代法.md: -------------------------------------------------------------------------------- 1 | 2 | ## 迭代法 3 | 4 | 是一种不断用旧值递推新值的过程,分精确迭代和近视迭代。是用来求方程和方程组近似根的方法。 5 | 6 | 7 | 迭代变量 8 | 迭代关系, 迭代关系选择不合理,会导致迭代失败 9 | 迭代过程控制,也就是迭代什么时候结束,不能无休止进行下去 10 | 11 | -------------------------------------------------------------------------------- /算法学习/Binary Tree/后缀树.md: -------------------------------------------------------------------------------- 1 | 2 | ## 后缀树(suffix tree) 3 | 4 | ###后缀树的应用 5 | 6 | 可以解决很多字符串的问题 7 | 8 | 1. 查找字符串S1是否在字符串S中 9 | 2. 指定字符串S1在字符串S中出现的次数 10 | 3. 字符串S中的最长重复子串 11 | 4. 2个字符串的最长公共部分 12 | 13 | 14 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c10.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int i=43; 5 | printf("%d\n",printf("%d",printf("%d",i))); 6 | return 0; 7 | } 8 | 9 | 10 | // printf 返回值是打印数据的长度 4321 11 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c9.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int main() 5 | { 6 | int a = (1,2); 7 | printf("a : %d\n",a); 8 | return 0; 9 | } 10 | 11 | // ,运算符优先级 最低 ,括号不能少 12 | // 13 | 14 | -------------------------------------------------------------------------------- /算法学习/Binary Tree/伸展树.md: -------------------------------------------------------------------------------- 1 | 2 | ## 伸展树 (splay tree) 3 | 4 | 伸展树是一种自平衡的二叉排序树。为什么需要这些自平衡的二叉排序树? 5 | 6 | n个节点的完全二叉树,其查找,删除的复杂度都是O(logN),但是如果频繁的插入删除,导致二叉树退化成一个n个节点的单链表,也就是`插入,查找复杂度趋于O(N)`,为了克服这个缺点,出现了很多二叉查找树的变形,如AVL树,红黑树,以及接下来介绍的 伸展树(splay tree)。 7 | 8 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/22.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int n; 5 | printf("Enter a number:\n"); 6 | scanf("%d",&n); // & 7 | 8 | printf("You entered %d \n",n); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/7.c: -------------------------------------------------------------------------------- 1 | 2 | #include "stdio.h" 3 | 4 | int main(){ 5 | 6 | int j,k,m; 7 | int i= (j=4,k=5,m=8); 8 | printf("%d\n", i); 9 | 10 | i= (j==4)?:0; 11 | printf("i=%d\n", i); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/8.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "stdio.h" 4 | 5 | int main(){ 6 | 7 | int a = 257; 8 | unsigned char *result = (unsigned char *)&a; 9 | printf("%d.%d.%d.%d\n", result[0],result[1],result[2],result[3] ); 10 | 11 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/24.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int i = 6; 5 | if( ((++i < 7) && ( i++/6)) || (++i <= 9)) 6 | ; 7 | printf("%d\n",i); 8 | return 0; 9 | } 10 | 11 | // && 优先级大于 || -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/28.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() 4 | { 5 | int* ptr1,*ptr2; 6 | ptr1 = malloc(sizeof(int)); 7 | ptr2 = ptr1; 8 | *ptr2 = 10; 9 | return 0; 10 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/leetcode.md: -------------------------------------------------------------------------------- 1 | 2 | 题目来自[leetcode](https://leetcode.com/) 3 | 4 | 5 | [LeetCode题解C++版](https://github.com/soulmachine/leetcode), 151道题完整版 6 | 7 | #### Minimum Height Trees 8 | 9 | 10 | 11 | #### Additive Number 12 | 13 | 14 | -------------------------------------------------------------------------------- /算法例题/[基本算法]递推/cover.md: -------------------------------------------------------------------------------- 1 | # 铺瓷砖 2 | ## 题目描述 3 | 用红色的 1×1 和黑色的 2×2 两种规格的瓷砖不重叠地铺满 n×3 的路面,求出有多少种不同的铺设方案。 4 | ## 输入格式 5 | 一行一个整数 n,0 2 12 | 13 | ### 输出样例 14 | > 3 15 | 16 | ## 数据范围与提示 -------------------------------------------------------------------------------- /算法学习/Graph Algorithms/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 图 4 | 5 | 6 | ### 图的存储结构 7 | 8 | * 对象和指针 9 | * 矩阵 10 | * 邻接表 11 | 12 | 13 | ### 图的操作 14 | 15 | #### 遍历 16 | 17 | * 广度优先 18 | * 深度优先 19 | 20 | Dijkstra 21 | A* 22 | 23 | 用于游戏编程和分布式计算 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /算法学习/Binary Tree/README.md: -------------------------------------------------------------------------------- 1 | 2 | * 二叉查找树 3 | * 赫夫曼编码 Huffman 4 | * 字典树trie(前缀树,单词查找树) 5 | * 伸展树 6 | * 后缀树 7 | 8 | * AVL树 9 | * 红黑树 10 | 11 | * B树 12 | * B+树 mysql索引使用B+树的数据结构 13 | * B*树 14 | * R树 15 | * Treap 树 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /算法例题/[csp-jx2019]/P5689多叉堆.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int MAXN=300000; 5 | const int MAXQ=300000; 6 | int size[MAXN]; 7 | long long heapnum[MAXN]; 8 | vector tree; 9 | int n,q; 10 | long long c[MAXN+1]; 11 | int main(){ 12 | 13 | } -------------------------------------------------------------------------------- /算法模版/MT/gcd-lcm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int gcd(int a, int b) { 4 | return !b ? a : gcd(b, a % b); 5 | } 6 | 7 | int main() { 8 | int n, m; scanf("%d%d", &n, &m); 9 | int GCD = gcd(n, m), LCM = n * m / GCD; 10 | printf("%d %d\n", GCD, LCM); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Analysis/穷举搜索法.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 穷举搜索法 4 | 5 | 或者叫蛮力法。对可能的解的众多候选按照某种顺序逐一枚举和检验。典型的问题如选择排序和冒泡排序。 6 | 7 | 8 | #### 背包问题 9 | 10 | 给定n个重量为 w1,w2,...,wn,定价为 v1,v2,...,vn 的物品,和一个沉重为W的背包,求这些物品中一个最有价值的子集,且能装入包中。 11 | 12 | 13 | 14 | #### 其它案例 15 | 16 | 选择排序 17 | 冒泡排序 18 | -------------------------------------------------------------------------------- /算法学习/Binary Tree/B树.md: -------------------------------------------------------------------------------- 1 | 2 | ## B树 3 | 4 | 平衡查找树,一种多路查找树。 5 | 6 | 能保证数据插入和删除情况下,任然保持执行效率。 7 | 8 | 一个M阶的B树满足: 9 | 10 | 1. 每个节点最多M个子节点 11 | 2. 除跟节点和叶节点外,其它每个节点至少有M/2个孩子 12 | 3. 根节点至少2个节点 13 | 4. 所有叶节点在同一层,叶节点不包含任何关键字信息 14 | 5. 有k个关键字的页节点包含k+1个孩子 15 | 16 | 也就是说:`根节点到每个叶节点的路径长度都是相同的。` 17 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/23.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int cnt = 5, a; 5 | 6 | do { 7 | a /= cnt; 8 | } while (cnt --); 9 | 10 | printf ("%d\n", a); 11 | return 0; 12 | } 13 | 14 | /// cnt==1 时,会发生除0错误 15 | 16 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/5.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "stdio.h" 4 | 5 | 6 | /* 7 | 8 | 1 是第一个元素 9 | 序列中元素被2或3或5整除 10 | 11 | */ 12 | unsigned long value_in_sequence(unsigned index){ 13 | 14 | 15 | 16 | 17 | } 18 | 19 | 20 | int main(){ 21 | 22 | 23 | 24 | return 0; 25 | } -------------------------------------------------------------------------------- /算法例题/[基本算法]递推/flag.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("flag.in"); 4 | ofstream fout("flag.out"); 5 | const int MAXN=46; 6 | int s[MAXN]; 7 | int n; 8 | int main(){ 9 | fin>>n; 10 | s[1]=2; 11 | s[2]=2; 12 | for(int i=3;i<=n;i++) s[i]=s[i-1]+s[i-2]; 13 | fout< 2 | int main() 3 | { 4 | int day,month,year; 5 | printf("Enter the date (dd-mm-yyyy) format including -'s:"); 6 | scanf("%d-%d-%d",&day,&month,&year); 7 | printf("The date you have entered is %d-%d-%d\n",day,month,year); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c18.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int i; 5 | i = 10; 6 | printf("i : %d\n",i); 7 | printf("sizeof(i++) is: %d\n",sizeof(i++)); 8 | printf("i : %d\n",i); 9 | return 0; 10 | } 11 | 12 | // sizeof()不会对传入的表达式计算 ,所以后面的输入还是i:10 13 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c12.c: -------------------------------------------------------------------------------- 1 | // FROM:http://www.gowrikumar.com/c/ 2 | #include 3 | int main() 4 | { 5 | float a = 12.5; 6 | printf("%d\n", a); 7 | //printf("%d\n", *(int *)&a); 8 | return 0; 9 | } 10 | 11 | // 浮点数 转 整形 ,用强制转换(int)a 12 | 13 | /* 14 | 浮点数的存储 15 | 16 | */ 17 | -------------------------------------------------------------------------------- /算法例题/[基本算法]分治和递归/car.md: -------------------------------------------------------------------------------- 1 | #小车问题 2 | ## 题目描述 3 | 甲、乙两人同时从A地出发要尽快同时赶到B地。出发时A地有一辆小车,可是这辆小车除了驾驶员外只能带一人。已知甲、乙两人的步行速度一样,且小于车的速度。问:怎样利用小车才能使两人尽快同时到达。 4 | ## 输入格式 5 | 一行:3个整数分别表示AB两地的距离s,人的步行速度a,车的速度b。 6 | ## 输出格式 7 | 一行:1个数,表示两人同时到达B地需要的最短时间。精确到小数点后2位。 8 | 样例 9 | ### 样例输入 10 | >120 5 25 11 | 12 | ### 样例输出 13 | >9.60 14 | ## 数据范围与提示 15 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c13-2.c: -------------------------------------------------------------------------------- 1 | #include "c13-1.c" 2 | 3 | extern int *arr; 4 | int main() 5 | { 6 | arr[1] = 100; 7 | return 0; 8 | } 9 | 10 | 11 | /** 12 | 类型并不匹配,所以导致这里的arr并没有指向c13-1.c中声明的arr[80],应该修改为 extern int arr[] 13 | 14 | int *arr 和 int arr[80] 区别? 15 | 16 | 17 | 18 | 19 | */ 20 | -------------------------------------------------------------------------------- /算法学习/Binary Tree/8-二叉堆(优先队列)/heap.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | void heap_build(int *a,int length){ 6 | 7 | 8 | } 9 | 10 | 11 | // 插入 12 | void heap_insert(int *a,int v){ 13 | 14 | 15 | 16 | } 17 | 18 | 19 | //删除,删除的元素放在value指向的内存中 20 | void heap_delete(int *a,int *value){ 21 | 22 | 23 | } 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/20.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define PrintInt(expr) printf("%s : %d\n",#expr,(expr)) 4 | int main() 5 | { 6 | int y = 100; 7 | int *p; 8 | p = malloc(sizeof(int)); 9 | *p = 10; 10 | y = y / *p; 11 | PrintInt(y); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c11.c: -------------------------------------------------------------------------------- 1 | #include 2 | void foobar1(void) 3 | { 4 | printf("In foobar1\n"); 5 | } 6 | 7 | void foobar2() 8 | { 9 | printf("In foobar2\n"); 10 | } 11 | 12 | int main() 13 | { 14 | char ch = 'a'; 15 | foobar1(); 16 | foobar2(33, ch); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /算法学习/String/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 字符串 3 | 4 | 字符串在计算机中的应用非常广泛,这里讨论有关字符串的最重要的算法: 5 | 6 | * 排序 7 | * 查找 8 | * 单词查找树 9 | * 子串查找 10 | * 正则表达式:正则表达式是模式匹配的基础,是一个一般化了的子字符串的查找问题,也是搜索工具grep的核心。 11 | * 模式匹配 12 | * grep 13 | * 数据压缩 14 | * 赫夫曼树 15 | * 游程编码 16 | 17 | 18 | ## 参考 19 | 20 | 《Algorithms》 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /算法例题/[基本算法]递推/cover.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("cover.in"); 4 | ofstream fout("cover.out"); 5 | 6 | const int MAXN=1001; 7 | int s[MAXN]; 8 | int n; 9 | 10 | int main(){ 11 | fin>>n; 12 | s[0]=1; 13 | s[1]=1; 14 | for(int i=2;i<=n;i++) s[i]=(s[i-1]+s[i-2]*2) % 12345; 15 | fout< 4 | int main() 5 | { 6 | char dummy[80]; 7 | printf("Enter a string:\n"); 8 | scanf("%[^a]",dummy); 9 | printf("%s\n",dummy); 10 | return 0; 11 | } 12 | 13 | /** 14 | 15 | 输入一个串,以字符'a'结尾 16 | */ 17 | 18 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c15.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #define SIZE 10 4 | void size(int arr[SIZE]) 5 | { 6 | printf("size of array is:%d\n",sizeof(arr)); 7 | } 8 | 9 | int main() 10 | { 11 | int arr[SIZE]; 12 | size(arr); 13 | return 0; 14 | } 15 | 16 | 17 | // 32位机器 4, 64位机器 8 -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum {false,true}; 4 | 5 | int main() 6 | { 7 | int i=1; 8 | do 9 | { 10 | printf("%d\n",i); 11 | i++; 12 | if(i < 15) 13 | continue; 14 | }while(false); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c5.c: -------------------------------------------------------------------------------- 1 | 2 | // FROM:http://www.gowrikumar.com/c/ 3 | #include 4 | #define f(a,b) a##b 5 | #define g(a) #a 6 | #define h(a) g(a) 7 | 8 | int main() 9 | { 10 | printf("%s\n",h(f(1,2))); // 11 | printf("%s\n",g(f(1,2))); // f(1,2) 12 | return 0; 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c11-2.c: -------------------------------------------------------------------------------- 1 | #include 2 | void foobar1(void) 3 | { 4 | printf("In foobar1\n"); 5 | } 6 | 7 | void foobar2() 8 | { 9 | printf("In foobar2\n"); 10 | } 11 | 12 | int main() 13 | { 14 | char ch = 'a'; 15 | foobar1(33, ch); 16 | foobar2(); 17 | return 0; 18 | } 19 | 20 | // compile error -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/bt1.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 二叉查找树变成双向链表 4 | */ 5 | 6 | strcut BSTreeNode{ 7 | 8 | int m_nValue; 9 | BSTreeNode *m_pLeft,m_pRight; 10 | 11 | }BSTree; 12 | 13 | void convertDoubleLinks(BSTree *root){ 14 | 15 | 16 | } 17 | 18 | 19 | int main(int argc, char const *argv[]) 20 | { 21 | 22 | return 0; 23 | } 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /算法例题/[c++基础]函数的递归调用和应用举例/tower.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int n; 5 | 6 | void hanno(int n,char a ,char c,char b){ 7 | if (n==1){ 8 | cout<"<>n; 18 | hanno(n,'A','C','B'); 19 | } -------------------------------------------------------------------------------- /算法模版/MT/inv-fermat.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef long long ll; 4 | 5 | ll n, p; 6 | 7 | static inline ll qpow(ll a, ll b) { 8 | ll res = 1; while(b) { 9 | if(b & 1) res = (res * a) % p; 10 | a = (a * a) % p, b >>= 1; 11 | } return res; 12 | } 13 | 14 | int main() { 15 | scanf("%lld%lld", &n, &p); 16 | printf("%lld\n", qpow(n, p - 2)); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c8.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int main() 5 | { 6 | float f=0.0f; 7 | int i; 8 | 9 | for(i=0;i<10;i++) 10 | f = f + 0.1f; 11 | 12 | if(f == 1.0f) 13 | printf("f is 1.0 \n"); 14 | else 15 | printf("f is NOT 1.0\n"); 16 | 17 | return 0; 18 | } 19 | 20 | // 浮点数判相等 21 | -------------------------------------------------------------------------------- /算法学习/Big Data/倒排索引(Inverted Index).md: -------------------------------------------------------------------------------- 1 | 2 | ## 倒排索引(Inverted Index) 3 | 4 | 也叫反向索引。是文档检索系统中最常用的数据结构。常规的索引是文档到关键词的映射,如果对应的文档是 5 | 6 | 7 | 8 | [Elasticsearch](https://github.com/elastic/elasticsearch)就是使用倒排索引(inverted index)的结构来做快速的全文搜索。ElasticSearch 不仅用于全文搜索, 还有非常强大的统计功能 (facets)。 9 | 10 | 携程,58,美团的分享中都提到ES构建实时日志系统,帮助定位系统问题。 11 | 12 | 13 | [Elasticsearch权威指南](http://es.xiaoleilu.com/index.html) 14 | 15 | 16 | -------------------------------------------------------------------------------- /算法模版/MT/nim.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define re register 3 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | int T, n; int main() { 6 | scanf("%d", &T); Rep(i, 0, T) { 7 | scanf("%d", &n); int ans = 0; 8 | re int x; rep(i, 1, n) scanf("%d", &x), ans ^= x; 9 | puts(ans ? "Yes" : "No"); 10 | } return 0; 11 | } 12 | -------------------------------------------------------------------------------- /算法例题/[c++基础]函数的递归调用和应用举例/ratf.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int n,k; 5 | 6 | int fzs(int x){ 7 | if (x>n>>k; 18 | cout< 2 | #include 3 | #define SIZE 15 4 | int main() 5 | { 6 | int *a, i; 7 | 8 | a = malloc(SIZE*sizeof(int)); 9 | 10 | for (i=0; i 2 | int main() 3 | { 4 | int a=1; 5 | switch(a) 6 | { int b=20; 7 | case 1: printf("b is %d\n",b); 8 | break; 9 | default:printf("b is %d\n",b); 10 | break; 11 | } 12 | return 0; 13 | } 14 | 15 | 16 | // In my computer ,output:b is 32767 switch中只会从case开始执行,b会随机输出 -------------------------------------------------------------------------------- /算法模版/MT/inv-linear.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define rep(i, a, b) for(int i = (a); i <= (b); ++ i) 4 | 5 | typedef long long ll; 6 | 7 | const int N = 1e7 + 9; 8 | 9 | ll n, p, inv[N]; 10 | 11 | int main() { 12 | inv[1] = 1; scanf("%lld%lld", &n, &p); 13 | puts("1"); rep(i, 2, n) { 14 | inv[i] = ((p - p / i) * inv[p % i]) % p; 15 | printf("%lld\n", inv[i]); 16 | } return 0; 17 | } -------------------------------------------------------------------------------- /算法例题/[c++基础]函数的递归调用和应用举例/number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int n; 5 | int yzh(int x){ 6 | int ret=0; 7 | for(int i=2;i<=x/2;i++){ 8 | if (x%i==0) ret+=i; 9 | } 10 | return ret; 11 | } 12 | int main(){ 13 | cin>>n; 14 | for(int a=2;a<=n;a++){ 15 | int b=yzh(a); 16 | if (b<=n&&yzh(b)==a) cout< 2 | using namespace std; 3 | 4 | ifstream fin("triangle.in"); 5 | ofstream fout("triangle.out"); 6 | 7 | int n; 8 | 9 | int main(){ 10 | fin>>n; 11 | long ans=0; 12 | for(int c=1;c<=n/2;c++){ 13 | for(int a=1;a<=c;a++){ 14 | int b=n-c-a; 15 | if (b>c||bc) ans++; 17 | } 18 | } 19 | fout< 2 | #define re register 3 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 4 | int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } 5 | int main() { 6 | int n, g, a; scanf("%d", &n); 7 | scanf("%d", &a); if(a < 0) a = -a; 8 | g = a; rep(i, 2, n) { 9 | scanf("%d", &a); 10 | if(a < 0) a = -a; 11 | g = gcd(g, a); 12 | } printf("%d", g); return 0; 13 | } 14 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() 4 | { 5 | while(1) 6 | { 7 | fprintf(stdout,"hello-out"); 8 | fprintf(stderr,"hello-err"); 9 | sleep(1); 10 | } 11 | return 0; 12 | } 13 | 14 | 15 | /* 16 | 17 | stdout 会缓冲输出 18 | 19 | \n 20 | fflush() 21 | 22 | setbuf(stdout,NULL) 23 | 24 | */ -------------------------------------------------------------------------------- /算法模版/MT/inv-exgcd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void exgcd(int a, int b, int &x, int &y) { 4 | if(!b) { x = 1, y = 0; return ; } 5 | exgcd(b, a % b, y, x); 6 | y -= x * (a / b); return ; 7 | } 8 | 9 | static inline int inv(int num, int p) { 10 | int x, y; exgcd(num, p, x, y); 11 | x = ((x % p) + p) % p; 12 | return x; 13 | } 14 | 15 | int main() { 16 | int n, p; scanf("%d%d", &n, &p); 17 | printf("%d\n", inv(n, p)); return 0; 18 | } -------------------------------------------------------------------------------- /算法学习/15 Classic Algorithms/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 15个经典基础算法 3 | 4 | 5 | * A*寻路算法 :求解最短路径 6 | * Dijkstra:最短路径算法 7 | >Dijkstra是荷兰的计算机科学家,提出”信号量和PV原语“,"解决哲学家就餐问题",”死锁“也是它提出来的 8 | 9 | * 动态规划 (Dynamic Programming) 10 | * BFS/DFS (广度/深度优先遍历) 11 | * 红黑树 一种自平衡的`二叉查找树` 12 | * KMP 字符串匹配算法 13 | * 遗传算法 14 | * 启发式搜索 15 | * 图像特征提取之SIFT算法 16 | * 傅立叶变换 17 | * Hash 18 | * 快速排序 19 | * SPFA(shortest path faster algorithm) 单元最短路径算法 20 | * 快递选择SELECT 21 | 22 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/2.c: -------------------------------------------------------------------------------- 1 | 2 | #include "stdio.h" 3 | 4 | 5 | int factorial(int n){ 6 | 7 | int ret=0; 8 | (n==0) || (ret=n+factorial(n-1)); 9 | return ret; 10 | } 11 | 12 | 13 | int main(){ 14 | 15 | int n=10; 16 | printf("factorial(10)= %d\n",factorial(10)); 17 | printf("factorial(5)= %d\n",factorial(5)); 18 | printf("factorial(1)= %d\n",factorial(1)); 19 | printf("factorial(0)= %d\n",factorial(0)); 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/27.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=3, b = 5; 5 | 6 | printf(&a["Ya!Hello! how is this? %s\n"], &b["junk/super"]); 7 | 8 | //printf(3["helloworld \n"]); 9 | 10 | printf("%c\n", 0["this"] ); 11 | 12 | printf(&a["WHAT%c%c%c %c%c %c !\n"], 1["this"], 13 | 2["beauty"],0["tool"],0["is"],3["sensitive"],4["CCCCCC"]); 14 | return 0; 15 | } 16 | 17 | /* 18 | 19 | 20 | 21 | */ -------------------------------------------------------------------------------- /算法学习/Link Table/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 链表 3 | 4 | * 链表 5 | * 双向链表 6 | 7 | ### 链表 8 | 9 | 这个就不介绍了。重点说下双向链表。 10 | 11 | 12 | ### 双向链表 13 | 14 | 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。 15 | 16 | 双向链表克服了单链表中访问某个节点前驱节点(插入,删除操作时),只能从头遍历的问题。 17 | 18 | ``` 19 | typedef int Value 20 | typedef struct Entry{ 21 | struct Entry *next,*prev; 22 | Value value; 23 | }DoubleLink; 24 | 25 | ``` 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /算法例题/[基本算法]阶段测试一/set.md: -------------------------------------------------------------------------------- 1 | # 集合的划分 2 | ## 题目描述 3 | 设s是一个具有n个元素的集合,s={a1,a2,…,an},现将s划分成k个满足下列条件的子集合s1,s2,…,sk,满足: 4 | (1)si≠ф 5 | (2)si∩sj=ф (1≤i,j≤k i≠j) 6 | (3)s1∪s2∪s3∪…∪sk=s 7 | 则s1,s2,…,sk是集合的一个划分。它相当于把s集合中的n个元素a1,a2,…,an放入k个(0 < k≤n < 30)无标号的盒子中,使得没有一个盒子为空。请你确定n个元素a1,a2,…,an放入k个无标号盒子中去的划分数s(n,k)。 8 | 9 | ## 输入格式 10 | 输入为一行两个数,表示 n 和 k 。 11 | ## 输出格式 12 | 输出一行为一个数,表示 s(n,k) 的值 13 | 样例 14 | ### 样例输入 15 | > 4 3 16 | 17 | ### 样例输出 18 | > 6 19 | ## 数据范围与提示 20 | -------------------------------------------------------------------------------- /算法学习/Algorithms Analysis/分治算法.md: -------------------------------------------------------------------------------- 1 | 2 | ### 分治算法 3 | 4 | 5 | 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,各个击破,分而治之。 6 | 7 | 分治算法常用`递归`实现 8 | 9 | 1) 问题缩小的小规模可以很容易解决 10 | 2) 问题可以分解为规模较小相同问题 11 | 3) 子问题的解可以合并为该问题的解 12 | 4) 各个子问题相互独立,(如果这条不满足,转为`动态规划`求解) 13 | 14 | 分治法的步骤: 15 | 1. 分解 16 | 2. 解决 17 | 3. 合并 18 | 19 | 20 | #### 大整数乘法 21 | 22 | 如 26542123532213598*345987342245553677884 23 | 24 | 25 | 26 | #### 其它案例 27 | 28 | 快速排序 29 | 归并排序 30 | 最大子数组和 31 | -------------------------------------------------------------------------------- /算法学习/Algorithms In DB/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 数据库系统中的算法 3 | 4 | 最近开始读《数据库系统实现》这本书,所以就想到把数据库里面用到的数据结构和算法做一个梳理。就有了这些文字。 5 | 6 | 7 | * 电梯算法 8 | * B树索引 9 | * R树索引 10 | * 位图索引 11 | * 一趟算法 12 | * 二趟算法 13 | * 基于排序 14 | * 基于散列 15 | * 连接树 16 | * 动态规划 17 | * 贪婪算法 18 | * 分布式并行数据库中的任务分配算法 19 | * 并行算法 20 | * 数据挖掘 21 | * 发现频繁项集的算法 22 | * 发现近似商品的算法 23 | * PageRank 24 | 25 | 26 | ## 参考 27 | 28 | 《数据库系统实现》 29 | 《redis设计与实现》 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /算法例题/[基本算法]阶段测试一/count.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | ifstream fin("count.in"); 5 | ofstream fout("count.out"); 6 | 7 | const int MAXN=1000; 8 | int s[MAXN+1]; 9 | int n; 10 | 11 | int solution(int k){ 12 | if (s[k]>0) return s[k]; 13 | int c=1; 14 | int mid=k/2; 15 | for(int i=1;i<=mid;i++) c+=solution(i); 16 | s[k]=c; 17 | return c; 18 | } 19 | 20 | int main(){ 21 | fin>>n; 22 | fout< 8 | 9 | ## 输入格式 10 | 一行一个整数 n,表示橱窗宽度(或者说彩带数目)。 11 | ## 输出格式 12 | 一行一个整数,表示装饰橱窗的彩带放置方案数。 13 | ## 样例 14 | ### 样例输入 15 | > 3 16 | 17 | ### 样例输出 18 | > 4 19 | 20 | ## 数据范围与提示 21 | 对 30% 的数据满足:1≤n≤15。 22 | 对 100% 的数据满足:1≤n≤45。 -------------------------------------------------------------------------------- /算法学习/Sort/8.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "stdio.h" 4 | 5 | int main(int argc, char const *argv[]) 6 | { 7 | 8 | int length=10; 9 | 10 | int j; 11 | for (int i = 0; i < length; ++i) 12 | { 13 | for (j = i+1 ; j < length; ++j) 14 | { 15 | printf("i=%d,j=%d\n",i,j ); 16 | } 17 | } 18 | 19 | 20 | for (int i = 0; i < length; ++i) 21 | { 22 | for (int k = i+1 ; k < length; ++k) 23 | { 24 | printf("i=%d,k=%d\n",i,k ); 25 | } 26 | } 27 | 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /算法模版/DP/lis-greedy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | 7 | const int N = 1e6 + 5; 8 | int a[N], d[N]; 9 | 10 | int main() { 11 | int n, len = 1; 12 | scanf("%d", &n); rep(i, 1, n) scanf("%d",&a[i]); 13 | d[1] = a[1]; rep(i, 2, n) { 14 | if(d[len] < a[i]) d[++ len] = a[i]; 15 | else *std::lower_bound(d + 1 , d + 1 + len , a[i]) = a[i]; 16 | } printf("%d",len); return 0; 17 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Analysis/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 算法分析思路 3 | 4 | 详细介绍每一种算法设计的思路,并为每种方法给出一个经典案例的详细解读,总结对应设计思路,最后给出其它案例,以供参考。 5 | 6 | 7 | * 迭代法 8 | * 穷举搜索法 9 | * 动态规划 10 | * 贪心算法 11 | * 回溯法 12 | * 分治算法 13 | * 递归 14 | 15 | 16 | 17 | ### 总结 18 | 19 | 贪心法、分治法、动态规划都是将问题归纳为根小的、相似的子问题,通过求解子问题产生全局最优解。 20 | 21 | `贪心法` 22 | 23 | `分治法` 24 | 25 | `动态规划` 26 | 27 | 28 | 29 | ## 参考 30 | 31 | 《算法设计与分析基础》 Anany Levitin 32 | http://www.chinaunix.net/old_jh/23/437639.html 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c1.c: -------------------------------------------------------------------------------- 1 | // FROM:http://www.gowrikumar.com/c/ 2 | 3 | #include 4 | 5 | #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) 6 | int array[] = {23,34,12,17,204,99,16}; 7 | 8 | int main() 9 | { 10 | int d; 11 | int n = TOTAL_ELEMENTS-2; 12 | for(d=-1;d <= (TOTAL_ELEMENTS-2);d++) 13 | printf("%d\n",array[d+1]); 14 | 15 | return 0; 16 | } 17 | 18 | 19 | /* 20 | 21 | d 是有符号数,sizeof()计算为无符号数,比较时d会转为无符号数,变成一个大数 22 | 23 | */ -------------------------------------------------------------------------------- /算法例题/[基本算法]贪心/delete.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | ifstream fin("delete.in"); 5 | ofstream fout("delete.out"); 6 | 7 | string num; 8 | int s; 9 | int main(){ 10 | fin>>num; 11 | fin>>s; 12 | int l=num.length(); 13 | if (s>=l) fout<<0; 14 | else { 15 | int i=0; 16 | for(int k=0;k 2 | int main() 3 | { 4 | int a=10; 5 | switch(a) 6 | { 7 | case '1': 8 | printf("ONE\n"); 9 | break; 10 | case '2': 11 | printf("TWO\n"); 12 | break; 13 | a: 14 | printf("NONE\n"); 15 | } 16 | return 0; 17 | } 18 | 19 | 20 | //什么也不输出, “default”这里随便什么都没有编译错误 -------------------------------------------------------------------------------- /算法例题/[基本算法]穷举/coin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | FILE *fpin,*fpout; 5 | 6 | long long n; 7 | 8 | int main(){ 9 | fpin=fopen("coin.in","r"); 10 | fpout=fopen("coin.out","w"); 11 | 12 | fscanf(fpin,"%lld",&n); 13 | while(n>0){ 14 | long long k=(-1+sqrt(1+8.0*n))/2; 15 | long long n_=(k+1)*k/2; 16 | long long ans=k*(k+1)*(2*k+1)/6; 17 | ans+=(k+1)*(n-n_); 18 | fprintf(fpout,"%lld\n",ans); 19 | fscanf(fpin,"%lld",&n); 20 | } 21 | } -------------------------------------------------------------------------------- /算法例题/[基本算法]贪心/kaj.md: -------------------------------------------------------------------------------- 1 | # 独木舟 2 | ## 题目描述 3 | 旅行社计划组织一个独木舟旅行。租用的独木舟都是一样的,最多乘两人,而且载重有一个限度。现在要节约费用,所以要尽可能地租用最少的舟。本题的任务是读入独木舟的载重量,参加旅行的人数以及每个人的体重,计算出所需要的独木舟数目。 4 | 5 | ## 输入格式 6 | 第 1 行是 w(80≤w≤200),表示每条独木舟最大的载重量。 7 | 第 2 行是正整数 n(1≤n≤30000),表示参加旅行的人数。 8 | 接下来的 n 行,每行是一个正整数 t i (5≤t i ≤w),表示每个人的重量。 9 | 10 | ## 输出格式 11 | 输出一行一个数,表示最少的独木舟数目。 12 | 13 | ## 样例 14 | ### 输入样例 15 | > 100 16 | 9 17 | 90 18 | 20 19 | 20 20 | 30 21 | 50 22 | 60 23 | 70 24 | 80 25 | 90 26 | 27 | ### 输出样例 28 | > 6 29 | ## 数据范围与提示 -------------------------------------------------------------------------------- /算法学习/Algorithms Analysis/动态规划.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 动态规划DP 4 | 5 | 复杂问题不能分解成几个子问题,而分解成一系列子问题; 6 | 7 | DP通常基于一个递推公式及一个(或多个)初始状态,当前子问题解由上一次子问题解推出。 8 | 9 | 状态 10 | 状态转移方程 11 | 递推关系 12 | 13 | 动态规划算法的关键在于解决冗余,以空间换时间的技术,需要存储过程中的各种状态。可以看着是`分治算法`+`解决冗余` 14 | 15 | 使用动态规划算法的问题的特征是`子问题的重叠性`,否则动态规划算法不具备优势 16 | 17 | 18 | ####基本步骤 19 | 20 | 1. 划分问题 21 | 2. 选择状态 22 | 3. 确定决策并写出状态转移方程 23 | 4. 写出规划方程 24 | 25 | 26 | #### 最长递增子序列 27 | 28 | 最长递增子序列(LIS Longest Increasing Subsequence) 29 | 30 | 31 | #### 其它案例 32 | 33 | 最短路径 34 | 35 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c17.c: -------------------------------------------------------------------------------- 1 | // FROM:http://www.gowrikumar.com/c/ 2 | 3 | #include 4 | int main() 5 | { 6 | 7 | char c; 8 | scanf("%c",&c); 9 | printf("%c\n",c); 10 | 11 | scanf(" %c",&c); 12 | printf("%c\n",c); 13 | 14 | return 0; 15 | } 16 | 17 | /* 18 | 19 | scanf("%c",&c) 和 scanf(" %c",&c) 区别 20 | 21 | 22 | 使用第二个scanf("%c",&c) 时,系统会将前一个scanf()输入的回车符号读入改变量。 23 | 这里为什么加一个“空格”就可以? 24 | scanf带“空格”后,会从输入缓冲区中skip 空白符(空格、tab,换行符),读取一个字符 25 | 26 | */ 27 | 28 | -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/c19.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0])) 5 | 6 | #define PrintInt(expr) printf("%s:%d\n",#expr,(expr)) 7 | int main() 8 | { 9 | /* The powers of 10 */ 10 | int pot[] = { 11 | 0001, 12 | 0010, 13 | 0100, 14 | 1000 15 | }; 16 | int i; 17 | 18 | for(i=0;i5 6 14 | 0 1 1 0 0 1 15 | 1 1 0 1 0 1 16 | 0 1 0 0 1 0 17 | 0 0 0 1 1 1 18 | 1 0 1 1 1 0 19 | 20 | ### 输出样例 21 | >7 -------------------------------------------------------------------------------- /算法例题/[c++基础]一维数组的统计查找和排序/height2.md: -------------------------------------------------------------------------------- 1 | # 美人松的高度2 2 | ## 题目描述 3 | 又到过年了,狗熊岭的动物们都忙碌起来,张灯结彩准备过年。李老板却要光头强砍掉一些百年美人松回去。美人松都是很高的,但是也不会超过长整型。现在光头强看到丛林里有 N 颗美人松按照从矮到高的顺序排好,当然每棵松的高度都是已知的。李老板要问光头强 M 次,每次询问高度为 K 的美人松有多少颗? 4 | ## 输入格式 5 | 第一行两个正整数 N 和 M,之间用一个空格隔开,1≤ N≤$10^6$,1≤M≤1000; 6 | 第二行 N 个正整数,之间用一个空格隔开,表示 N 棵美人松的高度; 7 | 第三行 M 个正整数 k,之间用一个空格隔开,表示 M 个询问,每次询问高度为 K 的美人松有多少棵,1≤k≤1000。 8 | ## 输出格式 9 | 一行 M 个整数,之间用一个空格隔开,分别表示对应每次询问高度为 K 的树的数量,如果没有,则输出 0 10 | 样例 11 | ### 输入样例 12 | > 5 2 13 | 2 3 3 4 5 14 | 3 4 15 | 16 | ### 输出样例 17 | > 2 1 18 | ## 数据范围与提示 19 | -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之动态规划的引入/P1216.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAXR=1000; 4 | int r; 5 | int a[MAXR+1][MAXR+1]; 6 | int dp[MAXR+1][MAXR+1]; 7 | int ans; 8 | int main(){ 9 | cin>>r; 10 | for(int i=1;i<=r;i++) 11 | for(int j=1;j<=i;j++){ 12 | cin>>a[i][j]; 13 | } 14 | for(int i=1;i<=r;i++){ 15 | for(int j=1;j<=i;j++){ 16 | dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j]; 17 | } 18 | } 19 | for(int j=1;j<=r;j++) ans=max(ans,dp[r][j]); 20 | cout< 2 | using namespace std; 3 | const int MAXN=10000; 4 | int n; 5 | int a[MAXN+1],b[MAXN+1]; 6 | int dp[MAXN+1][MAXN+1]; 7 | 8 | int main(){ 9 | cin>>n; 10 | for(int i=1;i<=n;i++) cin>>a[i]; 11 | for(int i=1;i<=n;i++) cin>>b[i]; 12 | 13 | for(int i=1;i<=n;i++) 14 | for(int j=1;j<=n;j++) { 15 | if (a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; 16 | else { 17 | dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 18 | } 19 | } 20 | cout< 2 | using namespace std; 3 | 4 | ifstream fin("ratio.in"); 5 | ofstream fout("ratio.out"); 6 | 7 | int A,B,L; 8 | int A_,B_; 9 | 10 | int main(){ 11 | fin>>A>>B>>L; 12 | A_=2*L;B_=1; 13 | for(int b=1;b<=L;b++){ 14 | for(int a=1;a<=L;a++){ 15 | if (a*B>=b*A){ 16 | if (a*B_ 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 6 | #define drep(i, a, b) for(re int i = (a); i >= (b); -- i) 7 | 8 | const int C = 1e6 + 5; 9 | 10 | int n, V, f[C]; 11 | 12 | int main() { 13 | scanf("%d%d", &n, &V); 14 | rep(i, 1, n) { 15 | re int w, v; 16 | scanf("%d%d", &w, &v); 17 | drep(j, V, v) 18 | f[j] = f[j - v] + w; 19 | } printf("%d\n", f[V]); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Analysis/回溯法.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 回溯法 4 | 5 | 也叫 `试探法`。 是一种选优搜索法,按照选优条件搜索,当搜索到某一步,发现原先选择并不优或达不到目标,就退回重新选择。 6 | 7 | 8 | 一般步骤 9 | 10 | 1. 针对问题,定义解空间( 这时候解空间是一个集合,且包含我们要找的最优解) 11 | 2. 组织解空间,确定易于搜索的解空间结构,通常组织成`树结构` 或 `图结构` 12 | 3. 深度优先搜索解空间,搜索过程中用剪枝函数避免无效搜索 13 | 14 | 回溯法求解问题时,一般是一边建树,一边遍历该树;且采用非递归方法。 15 | 16 | 17 | #### 八皇后问题 18 | 19 | 8x8的国际象棋棋盘上放置8个皇后,使得任何一个皇后都无法直接吃掉其他的皇后。任意2个皇后都不能处于同一个 横线,纵线,斜线上。 20 | 21 | 分析 22 | 1. 任意2个皇后不能同一行,也就是每个皇后占据一行,通用的,每个皇后也要占据一列 23 | 2. 一个斜线上也只有一个皇后 24 | 25 | 26 | 27 | #### 其它案例 28 | 29 | 迷宫问题 30 | 31 | 32 | -------------------------------------------------------------------------------- /算法学习/Algorithms Analysis/递归.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 递归 4 | 5 | 递归是一种设计和描述算法的有力工具。 递归算法执行过程分 `递推` 和 `回归` 两个阶段 6 | 7 | 在 `递推` 阶段,将大的问题分解成小的问题 8 | 在 `回归` 阶段,获得最简单问题的解后,逐级返回,依次得到稍微复杂情况的解,知道获得最终的结果 9 | 10 | 1) 确定递归公式 11 | 2) 确定边界条件 12 | 13 | 14 | #### 斐波那契数列 15 | 16 | fib(n)=fib(n-1)+fib(n-2) 17 | 18 | 19 | 递归实现 20 | ``` 21 | 22 | ``` 23 | 24 | 非递归实现 25 | ``` 26 | 27 | ``` 28 | 29 | #### 其它案例 30 | 31 | 阶乘计算 32 | 梵塔问题 (三根针1,2,3表示,1号从小到大n个盘子,先要都移到3号上,不能出现大盘压小盘,找出移动次数最少的方案) 33 | 快速排序 34 | 35 | 36 | 递归运行效率较低,因为有函数调用的开销,递归多次也可能造成栈溢出。 37 | 38 | -------------------------------------------------------------------------------- /算法模版/DP/knapsack-complete.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 6 | #define drep(i, a, b) for(re int i = (a); i >= (b); -- i) 7 | 8 | const int C = 1e6 + 5; 9 | 10 | int n, V, f[C]; 11 | 12 | int main() { 13 | scanf("%d%d", &n, &V); 14 | rep(i, 1, n) { 15 | re int w, v; 16 | scanf("%d%d", &w, &v); 17 | rep(j, v, V) 18 | f[j] = f[j - v] + w; 19 | } printf("%d\n", f[V]); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /算法例题/[c++基础]一维数组的统计查找和排序/paiming.md: -------------------------------------------------------------------------------- 1 | # 排名 2 | ## 题目描述 3 | 一年一度的江苏省小学生程序设计比赛开始了,组委会公布了所有学生的成绩,成绩按分数从高到低排名,成绩相同的按年级从低到高排。现在主办单位想知道每一个排名的学生前,有几位学生的年级低于他。 4 | 5 | ## 输入格式 6 | 第 1 行只有一个正整数 n(1≤n≤200),表示参赛的学生人数。 7 | 第 2~n+1 行,每行有两个正整数 s(0≤s≤400)和 g(1≤g≤6),之间用一个空格隔开,其中第 i+1 行的第一个数 s 表示第 i 个学生的成绩,第 i+1 行的第二个数 g 表示第 i 个学生的年级。 8 | ## 输出格式 9 | 输出 n 行,每行只有一个正整数,其中第 i 行的数 k 表示排第 i 名的学生前面有 k 个学生排名比他高,且年级比他低。 10 | 样例 11 | ### 输出样例 12 | > 5 13 | 300 5 14 | 200 6 15 | 350 4 16 | 400 6 17 | 250 5 18 | 19 | ### 输出样例 20 | > 0 21 | 0 22 | 1 23 | 1 24 | 3 25 | ## 数据范围与提示 -------------------------------------------------------------------------------- /算法例题/[c++基础]一维数组的统计查找和排序/count.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int MAXN=200000; 6 | int num[MAXN]; 7 | int n; 8 | int main(){ 9 | //输入 10 | cin>>n; 11 | for(int i=0;i>num[i]; 12 | //从小到大排序 13 | sort(num,num+n); 14 | //统计个数并输出 15 | int prev=num[0]; 16 | int k=1; 17 | for(int i=1;i 2 | using namespace std; 3 | FILE *fpin,*fpout; 4 | 5 | const int MAXN=20; 6 | int n,r; 7 | int combs[MAXN]; 8 | 9 | void dfs(int x,int k){ 10 | combs[k-1]=x; 11 | if (k==r){ 12 | for(int i=0;i 2 | #include 3 | 4 | using namespace std; 5 | ifstream fin("lcs.in"); 6 | ofstream fout("lcs.out"); 7 | const int MAXL=5000; 8 | string s1,s2; 9 | int dp[MAXL+1][MAXL+1]; 10 | int l1,l2; 11 | 12 | int main(){ 13 | fin>>s1; 14 | fin>>s2; 15 | l1=s1.length(); 16 | l2=s2.length(); 17 | 18 | for(int i=1;i<=l1;i++) 19 | for(int j=1;j<=l2;j++){ 20 | if (s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1; 21 | else dp[i][j]=max(dp[i][j-1],dp[i-1][j]); 22 | } 23 | fout< 2 | using namespace std; 3 | const int MAXN=10000; 4 | int carpets[MAXN+1][4]; 5 | int n; 6 | int x,y; 7 | int main(){ 8 | cin>>n; 9 | for(int i=1;i<=n;i++){ 10 | for(int j=0;j<4;j++) cin>>carpets[i][j]; 11 | } 12 | cin>>x>>y; 13 | int find=-1; 14 | for(int i=n;i>0;i--){ 15 | if (x>=carpets[i][0]&&x<=carpets[i][0]+carpets[i][2]&& 16 | y>=carpets[i][1]&&y<=carpets[i][1]+carpets[i][3]){ 17 | find=i; 18 | break; 19 | } 20 | } 21 | cout< 2 | using namespace std; 3 | ifstream fin("volume.in"); 4 | ofstream fout("volume.out"); 5 | 6 | const int MAXN=20; 7 | int v[MAXN]; 8 | int n,c; 9 | bool vflag[1001]; 10 | 11 | void dfs(int i,int sumv){ 12 | if (i>=n){ 13 | vflag[sumv]=true; 14 | }else { 15 | dfs(i+1,sumv); 16 | dfs(i+1,sumv+v[i]); 17 | } 18 | } 19 | int main(){ 20 | fin>>n; 21 | for(int i=0;i>v[i]; 23 | } 24 | dfs(0,0); 25 | c=0; 26 | for(int i=1;i<1001;i++) if (vflag[i]) c++; 27 | fout<> 1); 8 | result *= result; 9 | 10 | if (exponent & 1) result = result*base; 11 | 12 | return result; 13 | } 14 | 15 | int main(int argc, char const *argv[]) 16 | { 17 | printf("%f\n", Power(2,4)); 18 | printf("%f\n", Power(2.1,4)); 19 | printf("%f\n", Power(0,4)); 20 | printf("%f\n", Power(2,0)); 21 | printf("%f\n", Power(2,-3)); //负数就挂了 22 | return 0; 23 | } -------------------------------------------------------------------------------- /算法模版/MT/quick-pow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define re register 3 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 4 | const int N = 5e6 + 5; 5 | typedef long long ll; 6 | const ll mod = 998244352; 7 | ll a[N]; 8 | 9 | static inline ll qpow(ll a, ll b) { 10 | ll res = 1; while(b) { 11 | if(b & 1) res = (res * a) % mod; 12 | a = (a * a) % mod, b >>= 1; 13 | } return res; 14 | } 15 | 16 | int main() { 17 | ll x, n; scanf("%lld%lld", &x, &n); 18 | rep(i, 1, n) 19 | scanf("%lld", &a[i]), 20 | printf("%lld ", qpow(x, a[i])); 21 | puts(""); return 0; 22 | } -------------------------------------------------------------------------------- /算法例题/[基本算法]阶段测试一/set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | // ifstream fin("set.in"); 6 | // ofstream fout("set.out"); 7 | 8 | const int MAXN=30; 9 | int n,k; 10 | int s[MAXN+1][MAXN+1]; 11 | 12 | int main(){ 13 | cin>>n>>k; 14 | for(int i=1;i<=n;i++) s[i][1]=1; 15 | for(int i=2;i<=n;i++) 16 | for(int j=2;j<=i;j++){ 17 | s[i][j]=s[i-1][j-1]+j*s[i-1][j]; 18 | } 19 | for(int i=1;i<=n;i++){ 20 | for(int j=1;j<=k;j++) cout< 8 12 | 2 13 | 4 14 | 2 15 | 4 16 | 5 17 | 100 18 | 2 19 | 100 20 | 21 | ### 输出样例 22 | > 2 3 23 | 4 2 24 | 5 1 25 | 100 2 26 | ## 数据范围与提示 27 | 40%的数据满足:1<=n<=1000 28 | 80%的数据满足:1<=n<=50000 29 | 100%的数据满足:1<=n<=200000,每个数均不超过1500 000 000(1.5*10^9) -------------------------------------------------------------------------------- /算法例题/[基本算法]分治和递归/car.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | ifstream fin("car.in"); 5 | ofstream fout("car.out"); 6 | 7 | const float e=0.001; 8 | float s,a,b; 9 | 10 | 11 | int main(){ 12 | fin>>s>>a>>b; 13 | float left=0; 14 | float right=s/b; 15 | while(lefte) right=mid; 20 | else if (t1-t2>e) left=mid; 21 | else { 22 | fout< 2 | using namespace std; 3 | ifstream fin("flower.in"); 4 | ofstream fout("flower.out"); 5 | const int MAXN=100; 6 | int n,m; 7 | int a[MAXN+1]; 8 | int dp[MAXN+1][MAXN+1];//dp[i][j] 表示前i种花摆j盆的方案数 9 | 10 | int main(){ 11 | fin>>n>>m; 12 | for(int i=1;i<=n;i++) fin>>a[i]; 13 | 14 | for(int j=0;j<=m&&j<=a[1];j++) dp[1][j]=1; 15 | for(int i=2;i<=n;i++) 16 | for(int j=0;j<=m;j++) 17 | for(int k=0;k<=j&&k<=a[i];k++){ 18 | dp[i][j]+=dp[i-1][j-k]; 19 | dp[i][j]=dp[i][j] % 1000007; 20 | } 21 | 22 | fout< 2 | using namespace std; 3 | const int MAXN=500000; 4 | int n,type; 5 | int a[MAXN+1]; 6 | unsigned long long dp[MAXN+1],last[MAXN+1]; 7 | unsigned long long sum[MAXN+1]; 8 | 9 | int main(){ 10 | cin>>n>>type; 11 | for(int i=1;i<=n;i++) cin>>a[i]; 12 | sum[0]=0; 13 | for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; 14 | 15 | dp[0]=0; 16 | last[0]=0; 17 | for(int i=1;i<=n;i++){ 18 | for(int j=i;j>=1;j--){ 19 | if (sum[i]-sum[j-1]>=last[j-1]) { 20 | dp[i]=dp[j-1]+(sum[i]-sum[j-1])*(sum[i]-sum[j-1]); 21 | last[i]=sum[i]-sum[j-1]; 22 | break; 23 | } 24 | } 25 | } 26 | cout< 4 13 | 0 0 14 | 8 3 15 | 11 -1 16 | 10 0 17 | 18 | ### 输出样例 19 | > 14 20 | 21 | ### 样例说明 22 | 跳过 2 号城市。 23 | ## 数据范围与提示 24 | 对于 40% 的数据满足:n≤1000。 25 | 对于 100% 的数据满足:3≤n≤100000,-1000≤x i ,y i ≤1000。 -------------------------------------------------------------------------------- /算法例题/[基本算法]深度优先搜索/decompose.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("decompose.in"); 4 | ofstream fout("decompose.out"); 5 | 6 | int s[21]; 7 | int n; 8 | int count; 9 | 10 | void dfs (int dep,int k,int r){ 11 | for(int i=k;i<=r;i++){ 12 | s[dep]=i; 13 | int r1=r-i; 14 | if (r1==0) { 15 | for(int j=0;j<=dep;j++){ 16 | if (j>0) fout<<'+'<>n; 26 | dfs(0,1,n); 27 | fout<<"total="< 2 | using namespace std; 3 | 4 | int mi2[16]; 5 | int n; 6 | 7 | void express(int x){ 8 | for(int k=15;k>=0;k--){ 9 | if (x>=mi2[k]){ 10 | if (k==1) cout<<'2'; 11 | else if (k==0) cout<<"2(0)"; 12 | else { 13 | cout<<"2("; 14 | express(k); 15 | cout<<')'; 16 | } 17 | x=x-mi2[k]; 18 | if (x>0) cout<<'+'; 19 | else break; 20 | } 21 | } 22 | } 23 | int main(){ 24 | mi2[0]=1; 25 | for(int k=1;k<=15;k++) mi2[k]= mi2[k-1]*2; 26 | cin>>n; 27 | express(n); 28 | } -------------------------------------------------------------------------------- /算法模版/DP/lcs-lis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define re register 5 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 6 | 7 | const int N = 1e6 + 5; 8 | 9 | int a[N], b[N]; 10 | int d[N], stack[N], len; 11 | int main() { 12 | int n; scanf("%d",&n); 13 | Rep(i, 0, n) { 14 | scanf("%d",&a[i]); 15 | d[a[i]] = i + 1; 16 | } Rep(i, 0, n) { 17 | scanf("%d",&b[i]); 18 | b[i] = d[b[i]]; 19 | } stack[1] = b[0], len = 1; 20 | Rep(i, 0, n) { 21 | if(stack[len] < b[i]) stack[++ len] = b[i]; 22 | else *std::upper_bound(stack + 1,stack + 1 + len,b[i]) = b[i]; 23 | } printf("%d",len); return 0; 24 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]线段树与树状数组/P3373.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int MAXN=100000; 5 | int n,m,p; 6 | int a[MAXN+1]; 7 | struct Tag{ 8 | char op; 9 | int num; 10 | }; 11 | struct Node{ 12 | int l,r; 13 | int sum; 14 | vector lazy_tags; 15 | }; 16 | Node tree[(MAXN+1)*2]; 17 | void build(int i,int l,int r){ 18 | tree[i].l=l; 19 | tree[i].r=r; 20 | if (l==r) { 21 | tree[i].sum=a[l]; 22 | return; 23 | } 24 | int mid=(l+r)/2; 25 | build(i*2,l,mid); 26 | build(i*2+1,mid+1,r); 27 | 28 | } 29 | int main(){ 30 | cin>>n>>m>>p; 31 | for(int i=1;i<=n;i++) cin>>a[i]; 32 | 33 | } -------------------------------------------------------------------------------- /算法例题/[基本算法]动态规划/digtriangle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("digtriangle.in"); 4 | ofstream fout("digtriangle.out"); 5 | 6 | const int MAXN=100; 7 | int n; 8 | int number[MAXN][MAXN]; 9 | int dp[MAXN][MAXN]; 10 | int ans; 11 | 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>number[i][j]; 16 | dp[0][0]=number[0][0]; 17 | for(int i=1;ians) ans=dp[n-1][j]; 25 | fout< 2 | #include 3 | using namespace std; 4 | 5 | struct student{ 6 | int score,grade; 7 | }; 8 | bool compare(student a, student b) { 9 | if (a.score>b.score) return true; 10 | else if (a.score==b.score&&a.grade>n; 20 | for(int i=0;i>stus[i].score>>stus[i].grade; 22 | } 23 | sort(stus,stus+n,compare); 24 | for(int i=0;in){ 19 | sum-=small; 20 | small++; 21 | if (sum==n) 22 | { 23 | printf("%d, %d\n",small,big); 24 | } 25 | 26 | } 27 | 28 | big++; 29 | sum+=big; 30 | 31 | } 32 | 33 | 34 | 35 | } 36 | 37 | 38 | 39 | int main(int argc, char const *argv[]) 40 | { 41 | 42 | 43 | print_continuous_sequence_sum(115); 44 | 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之区间与环形动态规划/CF607B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAXN=500; 4 | int n; 5 | int c[MAXN+1]; 6 | int dp[MAXN+1][MAXN+1]; 7 | 8 | int main(){ 9 | cin>>n; 10 | for(int i=1;i<=n;i++) cin>>c[i]; 11 | for(int i=1;i<=n;i++) dp[i][i]=1; 12 | for(int i=1;i<=n-1;i++) 13 | if (c[i]==c[i+1]) dp[i][i+1]=1; 14 | else dp[i][i+1]=2; 15 | for(int len=3;len<=n;len++) 16 | for(int i=1;i<=n-len+1;i++){ 17 | int j=i+len-1; 18 | dp[i][j]=dp[i][i]+dp[i+1][j]; 19 | for(int k=i+1;k 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 6 | #define drep(i, a, b) for(re int i = (a); i >= (b); -- i) 7 | 8 | const int C = 1e6 + 5; 9 | 10 | static inline void upmax(int &a, int b){ 11 | if(a < b) a = b; return ; 12 | } 13 | 14 | int n, V, f[C]; 15 | 16 | int main() { 17 | scanf("%d%d", &n, &V); 18 | rep(k, 1, n) { 19 | re int cnt; scanf("%d", &cnt); 20 | drep(i, V, 0) rep(j, 1, cnt) { 21 | re int w, c; scanf("%d%d", &w, &c); 22 | if (i >= w) upmax(f[i], f[i - w] + c); 23 | } 24 | } printf("%d\n", f[V]); return 0; 25 | } -------------------------------------------------------------------------------- /算法学习/Algorithms Job Interview/测试代码/10.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "stdio.h" 4 | 5 | void generate(int a,int b,int N ,int * Q){ 6 | 7 | int p=1,q=1; 8 | int tmpA,tmpB; 9 | 10 | for (int i = 0; i < N; ++i) 11 | { 12 | tmpA = a*p; 13 | tmpB = b*q; 14 | 15 | if (tmpA>tmpB) 16 | { 17 | Q[i]=tmpB; 18 | q++; 19 | 20 | } 21 | else if(tmpA 2 | #include 3 | using namespace std; 4 | const int MAXN=20; 5 | 6 | int fz[MAXN][MAXN]; 7 | int n; 8 | int main(){ 9 | cin>>n; 10 | int c=0; 11 | int x=0; 12 | int y=n/2; 13 | do { 14 | c++; 15 | fz[x][y]=c; 16 | int new_x=(x-1+n)%n; 17 | int new_y=(y+1)%n; 18 | if (fz[new_x][new_y]>0){ 19 | new_x=(x+1)%n; 20 | new_y=y; 21 | } 22 | x=new_x; 23 | y=new_y; 24 | }while(c 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 6 | 7 | const int N = 1e7 + 5; 8 | 9 | bool vis[N]; int prime[N], p; 10 | 11 | static inline void euler(int lim) { 12 | rep(i, 2, lim) { 13 | if(!vis[i]) prime[++ p] = i; 14 | for(re int j = 1; j <= p && i * prime[j] <= lim; ++ j) { 15 | vis[i * prime[j]] = 1; 16 | if(!(i % prime[j])) 17 | break; 18 | } 19 | } 20 | return ; 21 | } 22 | 23 | int n; 24 | 25 | int main() { 26 | scanf("%d", &n); euler(n); 27 | rep(i, 1, p) printf("%d\n", prime[i]); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /算法例题/[c++基础]一维数组的统计查找和排序/paiming1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int MAXN=200; 5 | int score[MAXN]; 6 | int grade[MAXN]; 7 | 8 | int n; 9 | 10 | int main(){ 11 | cin>>n; 12 | for(int i=0;i>score[i]>>grade[i]; 14 | } 15 | 16 | for(int i=1;igrade[j+1])){ 19 | swap(score[j],score[j+1]); 20 | swap(grade[j],grade[j+1]); 21 | } 22 | } 23 | 24 | for(int i=0;i 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define down(i, a) for(re int i = (a); i; -- i) 6 | #define bitpre(i, a) for(re int i = (a); i; i -= (i & -i)) 7 | #define bitsuf(i, a, b) for(re int i = (a); i <= (b); i += (i & -i)) 8 | 9 | const int N = 1e6 + 5; 10 | const int mod = 998244353; 11 | 12 | int n, a[N], c[N]; 13 | 14 | int main() { 15 | scanf("%d", &n); re int fac = 1, ans = 1; 16 | down(i, n) scanf("%d",&a[i]); rep(i, 1, n) { 17 | re int s = 0; bitpre(j, a[i]) s += c[j]; 18 | ans = ( ans + 1ll * fac * s ) % mod, 19 | fac = 1ll * fac * i % mod; 20 | bitsuf(j, a[i], n) ++ c[j]; 21 | } printf("%d", ans); return 0; 22 | } 23 | -------------------------------------------------------------------------------- /算法模版/DP/lcs-normal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | 7 | const int N = 1e4 + 5; 8 | 9 | static inline int max(int a, int b) { 10 | return a > b ? a : b; 11 | } 12 | 13 | int n, m, tmp; 14 | char a[N], b[N]; 15 | int f[2][N]; 16 | 17 | int main() { 18 | scanf("%s",a + 1); n = strlen(a + 1); 19 | scanf("%s",b + 1); m = strlen(b + 1); 20 | int now = 0; rep(i, 0, n) { 21 | now ^= 1; rep(j, 1, m) { 22 | f[now][j] = max(f[now ^ 1][j],f[now][j - 1]); 23 | tmp = f[now ^ 1][j - 1] + 1; 24 | if(a[i] == b[j] && f[now][j] < tmp) f[now][j] = tmp; 25 | } 26 | } printf("%d",f[now][m]); return 0; 27 | } -------------------------------------------------------------------------------- /算法例题/[基本算法]穷举/comb.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | FILE *fpin,*fpout; 4 | 5 | const int MAXN=20; 6 | int n,r; 7 | int combs[MAXN]; 8 | 9 | int main(){ 10 | fpin=fopen("comb.in","r"); 11 | fpout=fopen("comb.out","w"); 12 | 13 | fscanf(fpin,"%d %d",&n,&r); 14 | int pos=0; 15 | combs[pos]=1; 16 | while(combs[0]<=n-r+1){ 17 | while(posn&&pos>0){ 27 | pos--; 28 | combs[pos]++; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之线性状态动态规划/p1439_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=100000; 6 | int n; 7 | int a[MAXN+1],b[MAXN+1]; 8 | int dp[MAXN+1]; 9 | int map[MAXN+1]; 10 | int f[MAXN+1]; 11 | int len; 12 | 13 | int main(){ 14 | cin>>n; 15 | for(int i=1;i<=n;i++) { 16 | cin>>a[i]; 17 | map[a[i]]=i; 18 | } 19 | for(int i=1;i<=n;i++) { 20 | cin>>b[i]; 21 | f[i]=INT_MIN; 22 | } 23 | len=0; 24 | f[0]=0; 25 | for(int i=1;i<=n;i++){ 26 | if (map[b[i]]>f[len]) f[++len]=map[b[i]]; 27 | else { 28 | int k=upper_bound(f,f+len+1,map[b[i]])-f; 29 | f[k]=map[b[i]]; 30 | } 31 | } 32 | cout< 2 | using namespace std; 3 | struct node { 4 | int id; 5 | node *next; 6 | }; 7 | node *head; 8 | node *cur,*last; 9 | int n,k; 10 | int main(){ 11 | cin>>n>>k; 12 | head=new(node); 13 | head->next=NULL; 14 | last=head; 15 | for(int i=1;i<=n;i++){ 16 | cur=new(node); 17 | cur->next=NULL; 18 | cur->id=i; 19 | last->next=cur; 20 | last=cur; 21 | } 22 | last->next=head->next; 23 | last=head; 24 | cur=head->next; 25 | int i=0; 26 | while(cur!=NULL&&cur!=last){ 27 | i++; 28 | if (i==k){ 29 | cout<id<<' '; 30 | last->next=cur->next; 31 | i=0; 32 | cur=cur->next; 33 | }else { 34 | last=cur; 35 | cur=last->next; 36 | } 37 | } 38 | cout<id; 39 | system("pause"); 40 | } -------------------------------------------------------------------------------- /算法例题/[洛谷2020十月赛]/P6858_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long 3 | const ll MOD=998244353; 4 | using namespace std; 5 | ll n,m; 6 | ll fast_pow(ll a,ll b){ 7 | ll ans=1; 8 | while(b){ 9 | if(b&1) ans=ans*a%MOD; 10 | a=a*a%MOD; 11 | b>>=1; 12 | } 13 | return ans; 14 | } 15 | 16 | ll inv(ll a,ll p){ 17 | return fast_pow(a,p-2); 18 | } 19 | 20 | ll f(ll n,ll m){ 21 | if (n==0&&m==0) return 0; 22 | if (n==0&&m==1) return 1; 23 | if (n>0&&m==0) return (1+(n-1)*n/2+2*(n-1)+1) % MOD; 24 | if (n>0&&m==1) return (n*(n+1)/2+2*n+1) % MOD; 25 | ll ret=((n+m+m*f(n,m-1)+n*f(n-1+m,1))%MOD)*inv(n+m,MOD) % MOD; 26 | return ret; 27 | } 28 | int main(){ 29 | cin>>n>>m; 30 | n=n%MOD; 31 | cout< 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 7 | 8 | const int N = 1e6 + 5; 9 | 10 | int n, a[N], b[N]; 11 | 12 | int main() { 13 | //scanf("%d", &n); Rep(i, 0, n) scanf("%d", &a[i]), b[i] = a[i]; 14 | //std::sort(b, b + n); int len = std::unique(b, b + n) - b; 15 | //Rep(i, 0, n) printf("%d\n", std::lower_bound(b, b + len, a[i]) - b); 16 | scanf("%d", &n); rep(i, 1, n) scanf("%d", &a[i]), b[i] = a[i]; 17 | std::sort(b + 1, b + n + 1); int len = std::unique(b + 1, b + n + 1) - b - 1; 18 | rep(i, 1, n) printf("%d\n", std::lower_bound(b + 1, b + len + 1, a[i]) - b); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /算法例题/[洛谷2020十月赛]/P6858.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long 3 | const ll MOD=998244353; 4 | const ll MAXM=1000000; 5 | using namespace std; 6 | ll n,m; 7 | ll f[MAXM+1]; 8 | 9 | ll fast_pow(ll a,ll b){ 10 | ll ans=1; 11 | while(b){ 12 | if(b&1) ans=ans*a%MOD; 13 | a=a*a%MOD; 14 | b>>=1; 15 | } 16 | return ans; 17 | } 18 | 19 | ll inv(ll a,ll p){ 20 | return fast_pow(a,p-2); 21 | } 22 | int main(){ 23 | cin>>n>>m; 24 | n=n%MOD; 25 | f[0]=(1+(n-1)*n/2+2*(n-1)+1)%MOD; 26 | f[1]=(n*(n+1)/2+2*n+1)%MOD; 27 | if (m>=2){ 28 | for(int i=2;i<=m;i++){ 29 | f[i]=((n+i+n*(((n+i-1)*(n+i)/2+2*(n+i-1)+1)%MOD)+i*f[i-1])%MOD)*inv(n+i,MOD)%MOD; 30 | } 31 | } 32 | cout< 2 | using namespace std; 3 | ifstream fin("book.in"); 4 | ofstream fout("book.out"); 5 | 6 | const int MAXN=20; 7 | int n; 8 | int favorit[MAXN+1][MAXN+1]; 9 | char c; 10 | int ans; 11 | bool flag[MAXN+1]; 12 | 13 | void dfs(int i){ 14 | if (i>n) ans++; 15 | else { 16 | for(int j=1;j<=n;j++) 17 | if (!flag[j]&&favorit[i][j]){ 18 | flag[j]=true; 19 | dfs(i+1); 20 | flag[j]=false; 21 | } 22 | } 23 | } 24 | int main(){ 25 | fin>>n; 26 | for(int i=1;i<=n;i++) 27 | for(int j=1;j<=n;j++) { 28 | fin>>c; 29 | favorit[i][j]=c-'0'; 30 | } 31 | ans=0; 32 | dfs(1); 33 | fout< 2 | using namespace std; 3 | 4 | ifstream fin("cow.in"); 5 | ofstream fout("cow.out"); 6 | const int MAXN=100001; 7 | char s[MAXN]; 8 | int c[MAXN],w[MAXN]; 9 | 10 | int n; 11 | long long ans; 12 | int main(){ 13 | fin>>n; 14 | fin>>s; 15 | if (s[0]=='C') c[0]=1; 16 | else c[0]=0; 17 | for(int i=1;i=0;i--){ 25 | if (s[i]=='W') w[i]=w[i+1]+1; 26 | else w[i]=w[i+1]; 27 | } 28 | ans=0; 29 | for(int i=0;i= 'A' && *start <= 'Z'){//大写 12 | if (*end >= 'a' && *end <= 'z'){ 13 | char tmp = *start; 14 | *start = *end; 15 | *end = tmp; 16 | 17 | start++; 18 | } 19 | end--; 20 | }else{//小写 21 | if (*end >= 'A' && *end <= 'Z'){ 22 | end--; 23 | } 24 | start++; 25 | } 26 | } 27 | return str; 28 | } 29 | 30 | int main(int argc, char const *argv[]) 31 | { 32 | char test[] = "HaJKPnobAACPc";//"char *test" always make "28767 bus error" 33 | printf("%s\n", proc(test)); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /算法模版/DS/linear-basis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define re register 4 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 5 | #define down(i, a) for(re int i = (a); ~i; -- i) 6 | 7 | typedef unsigned long long ull; 8 | const int N = 63; 9 | 10 | ull p[N + 5]; 11 | 12 | inline void ins(ull x){ 13 | down(i, N) if((x >> i) & 1){ 14 | if(!p[i]){ 15 | p[i] = x; 16 | return ; 17 | } 18 | x ^= p[i]; 19 | } return ; 20 | } 21 | 22 | ull query(ull x) { 23 | ull res = x; down(i, N) 24 | if((res ^ p[i]) > res) 25 | res ^= p[i]; 26 | return res; 27 | } 28 | 29 | int n; ull x; 30 | 31 | int main() { 32 | scanf("%d", &n); 33 | Rep(i, 0, n) scanf("%llu", &x), ins(x); 34 | printf("%llu\n", query(0)); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /算法模版/DP/lcis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define re register 3 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 4 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 5 | const int N = 1e4 + 5; 6 | int a[N], b[N], f[N], pos[N]; 7 | void output(int x) { 8 | if(!x) return; 9 | output(pos[x]); 10 | printf("%d ",b[x]); 11 | } 12 | int main() { 13 | int n, m, Max = 0; scanf("%d",&n); 14 | rep(i, 1, n) scanf("%d",&a[i]); 15 | scanf("%d", &m); rep(i, 1, m) scanf("%d",&b[i]); 16 | rep(i, 1, n) { 17 | re int t = 0; rep(j, 1, m) { 18 | if(a[i] == b[j]) f[j] = f[t] + 1, pos[j] = t; 19 | if(a[i] > b[j] && f[t] < f[j]) t = j; 20 | } 21 | } 22 | rep(i, 1, m) if(f[i] > f[Max]) Max = i; 23 | printf("%d\n",f[Max]); output(Max); return 0; 24 | } -------------------------------------------------------------------------------- /算法例题/[c++基础]一维数组的统计查找和排序/height2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int MAXN=1000000; 5 | int height[MAXN]; 6 | int n,m,k; 7 | int main(){ 8 | cin>>n>>m; 9 | for(int i=0;i>height[i]; 10 | for(int i=0;i>k; 12 | int left=0; 13 | int right=n-1; 14 | int c=0; 15 | while(left<=right){ 16 | int mid=(left+right)/2; 17 | if (height[mid]==k){ 18 | c=1; 19 | for(int p=mid-1;p>=0&&height[p]==k;p--) c++; 20 | for(int p=mid+1;p 2 | #include 3 | using namespace std; 4 | ifstream fin("max.in"); 5 | ofstream fout("max.out"); 6 | 7 | const int MAXN=20; 8 | string num[MAXN]; 9 | int n; 10 | 11 | bool cmp(string num1,string num2){ 12 | int l1=num1.length(); 13 | int l2=num2.length(); 14 | int i1=0,i2=0; 15 | while(1){ 16 | if (num1[i1]==num2[i2]){ 17 | i1++; 18 | i2++; 19 | if (i1==l1&&i2==l2) return false; 20 | else { 21 | i1=i1%l1; 22 | i2=i2%l2; 23 | } 24 | } 25 | else return (num1[i1]>num2[i2]); 26 | } 27 | } 28 | int main(){ 29 | fin>>n; 30 | for(int i=0;i>num[i]; 31 | sort(num,num+n,cmp); 32 | for(int i=0;i 2 | #include 3 | using namespace std; 4 | 5 | ifstream fin("kaj.in"); 6 | ofstream fout("kaj.out"); 7 | 8 | const int MAXN=30000; 9 | int w,n; 10 | int t[MAXN]; 11 | int ship[MAXN]; 12 | 13 | int main(){ 14 | fin>>w>>n; 15 | for(int i=0;i>t[i]; 16 | sort(t,t+n,greater()); 17 | int cnt=1; 18 | ship[0]=w; 19 | for(int i=0;i=t[i]){ 23 | if (ship[k]!=w) ship[k]=0; 24 | else ship[k]-=t[i]; 25 | can=true; 26 | break; 27 | } 28 | if (!can){ 29 | cnt++; 30 | ship[cnt-1]=w-t[i]; 31 | } 32 | } 33 | fout< 2 | using namespace std; 3 | ifstream fin("matches.in"); 4 | ofstream fout("matches.out"); 5 | 6 | int n; 7 | int huocai[2223]={6,2,5,5,4,5,6,3,7,6,0}; 8 | int get_huocai(int x){ 9 | if (huocai[x]>0) return huocai[x]; 10 | else { 11 | int r=x % 10; 12 | int q=x / 10; 13 | int ret=huocai[r]+get_huocai(q); 14 | huocai[x]=ret; 15 | return ret; 16 | } 17 | } 18 | int main(){ 19 | fin>>n; 20 | int k=0; 21 | n-=4; 22 | for(int a=0;a<=1111;a++){ 23 | for(int b=a;b<=1111;b++){ 24 | int c=a+b; 25 | int total=get_huocai(a)+get_huocai(b)+get_huocai(c); 26 | if (total==n){ 27 | if (a==b) k++; 28 | else k+=2; 29 | } 30 | } 31 | } 32 | fout< 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | 6 | const int N = 1e6 + 5; 7 | 8 | static inline void upmax(int &a, int b) { 9 | if(a < b) a = b; return ; 10 | } 11 | 12 | int n, ans, f[N]; 13 | struct Node{ int val, num; }z[N]; 14 | inline void modify(int x, int val) { 15 | while(x < N) { 16 | upmax(f[x], val); 17 | x += x & -x; 18 | } return ; 19 | } 20 | inline int query(int x) { 21 | int res = 0; while(x) { 22 | upmax(res, f[x]); 23 | x -= x & -x; 24 | } return res; 25 | } 26 | int main() 27 | { 28 | scanf("%d",&n); rep(i, 1, n) scanf("%d",&z[i].val); 29 | rep(i, 1, n) { 30 | int Max = query(z[i].val - 1); 31 | modify(z[i].val , ++ Max); 32 | upmax(ans,Max); 33 | } printf("%d",ans); return 0; 34 | } -------------------------------------------------------------------------------- /算法模版/SA/manacher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const int N = 3e7 + 5; 4 | 5 | char data[N]; int p[N], cnt, ans; 6 | 7 | #define re register 8 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 9 | static inline int min(int a, int b) { 10 | return a < b ? a : b; 11 | } 12 | 13 | int main() { 14 | char c = getchar(); data[0] = '!', data[cnt = 1] = '|'; 15 | while (c < 'a' || c > 'z') c = getchar(); 16 | while (c >= 'a' && c <= 'z') 17 | data[++ cnt] = c, data[++ cnt] = '|', c = getchar(); 18 | int r = 0,mid = 0; 19 | for (int t = 1;t <= cnt;t ++) { 20 | if(t <= r) p[t] = min(p[(mid << 1) - t],r - t + 1); 21 | while(data[t - p[t]] == data[t + p[t]]) ++ p[t]; 22 | if(p[t] + t > r) r = p[t] + t - 1,mid = t; 23 | if(p[t] > ans) ans = p[t]; 24 | } printf("%d\n", ans - 1); return 0; 25 | } -------------------------------------------------------------------------------- /算法学习/Big Data/双层桶划分.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 双层桶划分 4 | 5 | 双层桶不是一种数据结构,只是一种算法思维。分而治之思想。 6 | 7 | 当我们有一大推数据需要处理时,局限于各种资源限制(主要说内存)不能一次处理完成,这是需要将一大堆数据分成多个小段数据。通过处理各个小段数据完成最终任务。 8 | 9 | 双层这里是虚指,并不是一定把数据分成2份,也可能多份。比如下面几个问题: 10 | 11 | 1. 2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳这2.5亿个整数。 12 | 2. 5亿个int找它们的中位数 13 | 14 | 第一个问题,2.5亿(2^32=4,294,967,296)个数,我们将这2^32个数分到2^8=256个区域(文件中)。每个文件中的平均数字个数差不多 2^24个(1千7百万个)。 15 | 0~2^24 第一个文件,2^24~2^25第二个文件 16 | 17 | 18 | 假设32位机,装下这些数字需要的内存是 2^24*4=2^26=64MB,也可以不用将文件一次性读入内存而是采用流式读取。 19 | 20 | 然后对每个文件使用bitmap处理,每2bit(2-bitmap)表示一个整数,00表示整数未出现,01表示出现一次,10表示出现两次及其以上。这样,每个文件2^24个数字,最大数2^32/(8/2)=2^30=1GB内存 21 | 22 | 这个问题倒是更新是bitmap的应用,没有很好体现双层桶分治的优势。 23 | 24 | 25 | 第二个问题,首先我们将int划分为2^16个区域,然后读取数据统计落到各个区域里的数的个数,之后我们根据统计结果就可以判断中位数落到那个区域,同时知道这个区域中的第几大数刚好是中位数。然后第二次扫描我们只统计落在这个区域中的那些数就可以了。 26 | 27 | 28 | 29 | 适用问题领域是:`top-k,中位数,不重复或重复的数字` 30 | 31 | -------------------------------------------------------------------------------- /算法例题/[基本算法]贪心/water.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("water.in"); 7 | ofstream fout("water.out"); 8 | 9 | struct person{ 10 | int id; 11 | int time; 12 | 13 | bool operator<(const person other) const{ 14 | return time>n; 23 | for(int i=0;i>p[i].time; 26 | } 27 | sort(p,p+n); 28 | float totalwait=0; 29 | float wait=0; 30 | for(int i=0;i 2 | #include 3 | using namespace std; 4 | ifstream fin("choose.in"); 5 | ofstream fout("choose.out"); 6 | const int MAXN=100; 7 | vector graph[MAXN+1]; 8 | int dp_max[MAXN+1][MAXN+1]; 9 | int score[MAXN+1]; 10 | int n,m; 11 | void dp(int i){ 12 | dp_max[i][1]=score[i]; 13 | int s=graph[i].size(); 14 | for(int k=0;k0;w--) 18 | for(int v=w-1;v>0;v--) 19 | dp_max[i][w]=max(dp_max[i][w],dp_max[i][w-v]+dp_max[j][v]); 20 | } 21 | } 22 | int main(){ 23 | fin>>n>>m; 24 | for(int i=1;i<=n;i++){ 25 | int a,b; 26 | fin>>a>>b; 27 | graph[a].push_back(i); 28 | score[i]=b; 29 | } 30 | dp(0); 31 | fout< 4 | #include 5 | void Error(char* s) 6 | { 7 | printf(s); 8 | return; 9 | } 10 | 11 | int main() 12 | { 13 | int *p; 14 | p = malloc(sizeof(int)); 15 | if(p == NULL) 16 | { 17 | Error("Could not allocate the memory\n"); 18 | Error("Quitting....\n"); 19 | exit(1); 20 | } 21 | else 22 | { 23 | /*some stuff to use p*/ 24 | Error("Could not allocate the memory\n"); 25 | Error("Quitting....\n"); 26 | Error(5); 27 | } 28 | return 0; 29 | } 30 | 31 | /* 32 | 33 | 潜在的问题是: 34 | 35 | Error函数中,如果输入的参数不是字符串,比如传一个整数5,5被转成一个内存地址,printf这时候访问就会出问题了。 36 | $1 = 0x5 37 | 38 | */ -------------------------------------------------------------------------------- /算法例题/[提高训练]动态规划之区间DP/energy.cpp: -------------------------------------------------------------------------------- 1 | //#1002. 「一本通 5.1 例 2」能量项链 2 | #include 3 | using namespace std; 4 | ifstream fin("energy.in"); 5 | ofstream fout("energy.out"); 6 | 7 | const int MAXN=1000; 8 | int head[MAXN*2]; 9 | int dp_max[MAXN*2][MAXN+1];//dp_max[i][j]表示以第i颗珠子为起始的,长度为j的区间(即[i,i+j-1])里,所有珠子合并所能得到的最大能量 10 | int n; 11 | 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>head[i]; 16 | head[i+n]=head[i]; 17 | } 18 | int m=2*n-1; 19 | for(int j=2;j<=n;j++) //j为区间长度 20 | for(int i=0;ilastMax) lastMax=dp_max[i][n]; 28 | fout< 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | 7 | const int N = 1e6 + 5; 8 | const int BIT = 20 + 5; 9 | 10 | int f[N][BIT]; 11 | 12 | static inline int max(int a, int b){ 13 | return a > b ? a : b; 14 | } 15 | 16 | inline int query(int l, int r) { 17 | int k = log2(r - l + 1); 18 | return max(f[l][k], f[r - (1 << k) + 1][k]); 19 | } 20 | 21 | int main() { 22 | re int n, m; scanf("%d %d", &n, &m); 23 | rep(i, 1, n) scanf("%d", &f[i][0]); 24 | re int lim = log2(n); rep(j, 1, lim) 25 | for (re int i = 1; i + (1 << j) - 1 <= n; ++ i) 26 | f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]); 27 | while(m --) { 28 | re int l, r; scanf("%d %d", &l, &r); 29 | printf("%d\n", query(l, r)); 30 | } return 0; 31 | } -------------------------------------------------------------------------------- /算法模版/AL/three-divide.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define Down(i, a) for(re int i = (a); ~i; -- i) 6 | 7 | typedef long double ldb; 8 | typedef double db; 9 | 10 | const ldb eps = 1e-10; 11 | const int N = 20; 12 | 13 | db l, r, a[N]; int n; 14 | 15 | inline db f(db x) { 16 | db u[N]; u[n] = a[n]; Down(i, n - 1) 17 | u[i] = u[i + 1] * x + a[i]; 18 | return u[0]; 19 | } 20 | 21 | static inline db check(db x) { 22 | db dx = eps, dy = f(x + dx) - f(x); 23 | return dy / dx; 24 | } 25 | 26 | int main() { 27 | scanf("%d%lf%lf",&n, &l, &r); 28 | rep(i, 0, n) scanf("%lf",&a[n - i]); 29 | db mid; while(r - l > eps) { 30 | mid = (l + r) / 2; 31 | if(check(mid) > 0) l = mid; 32 | else r = mid; 33 | } printf("%.5lf\n", mid); return 0; 34 | } 35 | -------------------------------------------------------------------------------- /算法例题/[基本算法]动态规划/missile1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | ifstream fin("missile.in"); 6 | ofstream fout("missile.out"); 7 | const int MAXN=1000; 8 | int n; 9 | int high[MAXN]; 10 | int l1,l2; 11 | int d1[MAXN],d2[MAXN]; 12 | 13 | int main(){ 14 | fin>>n; 15 | for(int i=0;i>high[i]; 16 | l1=1; 17 | d1[0]=high[0]; 18 | l2=1; 19 | d2[0]=high[0]; 20 | 21 | for(int i=1;i())-d1; 25 | d1[k]=high[i]; 26 | } 27 | if (high[i]>d2[l2-1]) d2[l2++]=high[i]; 28 | else { 29 | int k=lower_bound(d2,d2+l2,high[i])-d2; 30 | d2[k]=high[i]; 31 | } 32 | } 33 | 34 | //输出 35 | fout< 2 | #include 3 | using namespace std; 4 | const int MAXN=100000; 5 | const int MAXPOW=20; 6 | int a[MAXN+1]; 7 | int maxv[MAXN+1][MAXPOW+1]; 8 | int n,m; 9 | int query(int l,int r){ 10 | int ret=0; 11 | for(int j=MAXPOW;j>=0;j--){ 12 | if (l+(1<divider){ 14 | 15 | divider++; 16 | result = integer/divider; 17 | 18 | } 19 | 20 | if (result!=divider) 21 | { 22 | return -1; 23 | } 24 | 25 | return result; 26 | } 27 | 28 | 29 | int main(int argc, char const *argv[]) 30 | { 31 | // 243,1849(43),289(17), 64(8) 32 | 33 | int a[] = {1849,144,243,289,64,1194877489}; 34 | for (int i = 0; i < sizeof(a)/sizeof(int); ++i) 35 | { 36 | int ret = isSquare(a[i]); 37 | 38 | if (ret==-1) 39 | { 40 | printf("%d 不是某个数的平方\n",a[i]); 41 | }else{ 42 | 43 | printf("%d 是 %d 的平方\n", a[i], ret); 44 | } 45 | 46 | } 47 | 48 | return 0; 49 | } 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /算法例题/[提高训练]动态规划之树型DP/strategi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | ifstream fin("strategi.in"); 5 | ofstream fout("strategi.out"); 6 | 7 | const int MAXN=1500; 8 | vector graph[MAXN+1]; 9 | int dp_min[MAXN+1][2]; 10 | int n; 11 | 12 | void dp(int x){ 13 | int s=graph[x].size(); 14 | int s0=0,s1=0; 15 | for(int k=0;k>n; 26 | for(int i=0;i>x>>b; 29 | for(int j=0;j>y; 32 | graph[x].push_back(y); 33 | } 34 | } 35 | dp(0); 36 | int ans=min(dp_min[0][0],dp_min[0][1]); 37 | fout< 2 | #include 3 | using namespace std; 4 | ifstream fin("book.in"); 5 | ofstream fout("book.out"); 6 | const int MAXM=500; 7 | const int INF=0x7fffffff; 8 | int m,k; 9 | int page[MAXM+1]; 10 | int totalPage[MAXM+1][MAXM+1]; 11 | int dp[MAXM+1][MAXM+1];//dp[i][j] 表示前i本书籍分配给前j个人所花的最短抄写时间 12 | 13 | int main(){ 14 | fin>>m>>k; 15 | for(int i=1;i<=m;i++) fin>>page[i]; 16 | 17 | for(int i=1;i<=m;i++) 18 | for(int j=i;j<=m;j++) 19 | totalPage[i][j]=totalPage[i][j-1]+page[j]; 20 | 21 | for(int i=1;i<=m;i++) 22 | for(int j=1;j<=i;j++) dp[i][j]=INF; 23 | 24 | for(int i=1;i<=m;i++) dp[i][1]=totalPage[1][i]; 25 | for(int i=2;i<=m;i++) 26 | for(int j=2;j<=i;j++) 27 | for(int p=j-1;p 2 | using namespace std; 3 | ifstream fin("chorus.in"); 4 | ofstream fout("chorus.out"); 5 | const int MAXN=1000; 6 | int n; 7 | int high[MAXN]; 8 | int dp[2][MAXN]; //dp[0][i] 表示编号 0——i-1 的学生中,以第i个学生身高为末尾的最长递增子序列 9 | //dp[1][i] 表示编号 i-1——n-1 的学生中,以第i个学生身高为起点的最长递减子序列 10 | int ans; 11 | 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>high[i]; 15 | for(int i=0;i=0;i--) 24 | for(int k=n-1;k>i;k--) 25 | if (high[k]ans) ans=s; 30 | } 31 | fout< 3 | using namespace std; 4 | const int MAXN=50000,key=10000; 5 | struct stack{ 6 | long ele[MAXN]; 7 | int top=0; 8 | void push(long x){ 9 | ele[top]=x; 10 | top++; 11 | } 12 | void pop(){ 13 | top--; 14 | } 15 | long get_top(){ 16 | return ele[top-1]; 17 | } 18 | bool empty(){ 19 | return top==0; 20 | } 21 | }; 22 | stack s; 23 | 24 | int main(){ 25 | int x; 26 | cin>>x; 27 | s.push(x); 28 | char op; 29 | while(cin>>op){ 30 | cin>>x; 31 | if (op=='*'){ 32 | int y=s.get_top(); 33 | x=(y*x)%key; 34 | s.pop(); 35 | s.push(x); 36 | }else if(op=='+') { 37 | s.push(x); 38 | } 39 | } 40 | int ret=0; 41 | while(!s.empty()){ 42 | x=s.get_top(); 43 | ret=(ret+x)%key; 44 | s.pop(); 45 | } 46 | cout< 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 6 | 7 | typedef long long ll; 8 | 9 | const int N = 10 + 5; 10 | 11 | ll n, ans, a[N], b[N], c[N], inv[N], M, m[N]; 12 | 13 | void exgcd(ll a, ll b, ll &x, ll &y) { 14 | if(!b) { x = 1, y = 0; return ; } 15 | exgcd(b, a % b, y, x); 16 | y -= x * (a / b); return ; 17 | } 18 | 19 | static inline ll Inv(ll num, ll p) { 20 | ll x, y; exgcd(num, p, x, y); 21 | x = ((x % p) + p) % p; 22 | return x; 23 | } 24 | 25 | int main() { 26 | scanf("%lld", &n); M = 1; 27 | rep(i, 1, n) scanf("%lld%lld", &a[i], &b[i]), M = M * a[i]; 28 | rep(i, 1, n) m[i] = M / a[i], inv[i] = Inv(m[i], a[i]); 29 | rep(i, 1, n) c[i] = inv[i] * m[i], ans = (ans + c[i] * b[i]) % M; 30 | ans = ((ans % M) + M) % M, printf("%lld\n", ans); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /算法例题/[提高训练]动态规划之区间DP/kh.cpp: -------------------------------------------------------------------------------- 1 | //#1004. 「一本通 5.1 练习 1」括号配对 2 | #include 3 | using namespace std; 4 | ifstream fin("kh.in"); 5 | ofstream fout("kh.out"); 6 | const int MAXN=100; 7 | string s; 8 | int dp_min[MAXN][MAXN]; 9 | 10 | int main(){ 11 | fin>>s; 12 | int len=s.length(); 13 | for(int i=0;i 2 | using namespace std; 3 | 4 | ifstream fin("bishop.in"); 5 | ofstream fout("bishop.out"); 6 | 7 | const int MAXN=20; 8 | int n,m,maxk; 9 | bool flag[MAXN][MAXN]; 10 | 11 | void MarkBackslash(int x,int y,bool val){ 12 | int b=y-x; 13 | for(int x_=0;x_=0&&y_n+m-2) return; 21 | for(int x=0;x=0&&ymaxk) maxk=k; 27 | MarkBackslash(x,y,true); 28 | SearchSlash(b+1,k); 29 | MarkBackslash(x,y,false); 30 | k--; 31 | } 32 | } 33 | } 34 | } 35 | int main(){ 36 | fin>>n>>m; 37 | SearchSlash(0,0); 38 | fout< 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=50; 6 | int n; 7 | char c[MAXN+1]; 8 | int dp[MAXN+1][MAXN+1]; 9 | 10 | int main(){ 11 | int i=0; 12 | char a; 13 | while(cin>>a){ 14 | i++; 15 | c[i]=a; 16 | } 17 | n=i; 18 | for(int i=1;i<=n;i++) dp[i][i]=1; 19 | for(int i=1;i k) high = mid-1; 34 | } 35 | 36 | return -1; 37 | } 38 | ``` 39 | 40 | #### 分块查找 41 | 42 | 块内无序,块之间有序;可以先二分查找定位到块,然后再到块中顺序查找。 43 | 44 | 45 | #### 动态查找 46 | 47 | 这里之所以叫 动态查找表,是因为表结构是查找的过程中动态生成的。查找结构通常是二叉排序树,AVL树,B- ,B+等。这部分的内容可以去看『二叉树』章节 48 | 49 | #### 哈希表 50 | 51 | 哈希表以复杂度O(1)的成绩位列所有查找算法之首,大量查找的数据结构中都可以看到哈希表的应用。 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /算法例题/[基本算法]递推/marathon.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | ifstream fin("marathon.in"); 5 | ofstream fout("marathon.out"); 6 | struct CITY{ 7 | int x=0; 8 | int y=0; 9 | int distance_to(CITY other){ 10 | return abs(x-other.x)+abs(y-other.y); 11 | } 12 | }; 13 | const int MAXN=100001; 14 | CITY cities[MAXN]; 15 | int total_dis[MAXN]; 16 | int min_dis[MAXN]; 17 | 18 | int n; 19 | int main(){ 20 | fin>>n; 21 | for(int i=1;i<=n;i++){ 22 | fin>>cities[i].x>>cities[i].y; 23 | } 24 | total_dis[1]=0; 25 | for(int i=2;i<=n;i++) total_dis[i]=total_dis[i-1]+cities[i-1].distance_to(cities[i]); 26 | min_dis[1]=0; 27 | min_dis[2]=total_dis[2]; 28 | for(int i=3;i<=n;i++){ 29 | int d1=total_dis[i-2]+cities[i-2].distance_to(cities[i]); 30 | int d2=min_dis[i-1]+cities[i-1].distance_to(cities[i]); 31 | min_dis[i]=min(d1,d2); 32 | } 33 | fout<1) 8 | { 9 | return s[0]=='-'?string_to_integer(s,length-1)*10-(s[length-1]-'0'):string_to_integer(s,length-1)*10+s[length-1]-'0'; 10 | }else{ 11 | return s[0]=='-'?-1/10:s[0]-'0'; 12 | 13 | } 14 | } 15 | 16 | /* 问题: 17 | 1. s是空字符串 18 | 2. s传参为非数字字符 19 | 3. 超出整数所能表示范围 20 | */ 21 | 22 | 23 | int main(){ 24 | 25 | char *s = "4323"; 26 | 27 | printf("integer == %d\n",string_to_integer(s,strlen(s)) ); 28 | printf("integer == %d\n",string_to_integer("12342",5)); 29 | printf("integer == %d\n",string_to_integer("-11",3) ); 30 | printf("integer == %d\n",string_to_integer("-5",2) ); 31 | printf("integer == %d\n", string_to_integer("3",1)); 32 | 33 | printf("integer == %d\n", string_to_integer("abcd",4)); 34 | printf("integer == %d\n", string_to_integer("a",1)); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /算法例题/[基本算法]贪心/match.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("match.in"); 4 | ofstream fout("match.out"); 5 | 6 | const int MAXN=1000; 7 | int huocai[MAXN]; 8 | int n; 9 | int mi2[17]; 10 | 11 | int main(){ 12 | mi2[0]=1; 13 | for(int i=1;i<17;i++) mi2[i]=mi2[i-1]*2; 14 | fin>>n; 15 | for(int i=0;i>huocai[i]; 16 | int ret=huocai[0]; 17 | for(int i=1;i0) k--; 22 | for(int i=0;i0){ 25 | int old=huocai[i]; 26 | huocai[i]=huocai[i]^ret; 27 | inc=huocai[i]-old; 28 | fout<<-1*inc<<' '< 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=20; 6 | int fz[MAXN+2][MAXN+2]; 7 | int dir_off[4][2]={{0,1},{-1,0},{0,-1},{1,0}}; 8 | 9 | int n; 10 | int main(){ 11 | cin>>n; 12 | for(int i=0;i 2 | #include 3 | using namespace std; 4 | const int MAXN=100000; 5 | int a[MAXN+1],b[MAXN+1]; 6 | int c[MAXN+1]; 7 | int n; 8 | priority_queue maxheap; 9 | int main(){ 10 | cin>>n; 11 | for(int i=0;i>a[i]; 12 | for(int i=0;i>b[i]; 13 | int s=0; 14 | for(int i=0;i=maxheap.top()) break; 22 | else{ 23 | maxheap.pop(); 24 | maxheap.push(sum); 25 | } 26 | } 27 | } 28 | int i=0; 29 | while(!maxheap.empty()){ 30 | c[n-1-i]=maxheap.top(); 31 | maxheap.pop(); 32 | i++; 33 | } 34 | for(int i=0;i 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN = 100000; 6 | int n; 7 | int high[MAXN]; 8 | int l1, l2; 9 | int d1[MAXN], d2[MAXN]; 10 | 11 | int main() { 12 | int i=0; 13 | long a; 14 | while(cin>>a){ 15 | high[i]=a; 16 | i++; 17 | } 18 | n=i; 19 | l1 = 1; 20 | d1[0] = high[0]; 21 | l2 = 1; 22 | d2[0] = high[0]; 23 | 24 | for (int i = 1; i < n; i++) { 25 | if (high[i] <= d1[l1 - 1]) 26 | d1[l1++] = high[i]; 27 | else { 28 | int k = upper_bound(d1, d1 + l1, high[i], greater()) - d1; 29 | d1[k] = high[i]; 30 | } 31 | if (high[i] > d2[l2 - 1]) 32 | d2[l2++] = high[i]; 33 | else { 34 | int k = lower_bound(d2, d2 + l2, high[i]) - d2; 35 | d2[k] = high[i]; 36 | } 37 | } 38 | 39 | //输出 40 | cout << l1 << endl << l2; 41 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之动态规划的引入/P1434.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAXN=100; 4 | int r,c; 5 | int high[MAXN][MAXN]; 6 | int dp[MAXN][MAXN]; 7 | int direct_offset[4][2]={{0,1},{0,-1},{-1,0},{1,0}}; 8 | void tree_dp(int i,int j){ 9 | int maxsublength=0; 10 | for(int k=0;k<4;k++){ 11 | int newi=i+direct_offset[k][0]; 12 | int newj=j+direct_offset[k][1]; 13 | if (newi<0||newi>=r||newj<0||newj>=c) continue; 14 | if (high[i][j]<=high[newi][newj]) continue; 15 | if (dp[newi][newj]==0) tree_dp(newi,newj); 16 | maxsublength=max(maxsublength,dp[newi][newj]); 17 | } 18 | dp[i][j]=maxsublength+1; 19 | } 20 | int ans; 21 | int main(){ 22 | cin>>r>>c; 23 | for(int i=0;i>high[i][j]; 25 | for(int i=0;i 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | 6 | typedef long long ll; 7 | 8 | void exgcd(ll a, ll b, ll &x, ll &y) { 9 | if(!b) { x = 1, y = 0; return ; } 10 | exgcd(b, a % b, y, x); 11 | y -= x * (a / b); return ; 12 | } 13 | 14 | static inline ll inv(ll num, ll p) { 15 | ll x, y; exgcd(num, p, x, y); 16 | x = ((x % p) + p) % p; 17 | return x; 18 | } 19 | 20 | static inline ll C(ll n, ll m, ll p) { 21 | if(m > n) return 0; ll ans = 1; 22 | rep(i, m + 1, n) ans = (ans * i) % p; 23 | rep(i, 2, n - m) ans = (ans * inv(i, p)) % p; 24 | return ans; 25 | } 26 | 27 | ll lucas(ll n, ll m, ll p) { 28 | return m ? lucas(n / p, m / p, p) * C(n % p, m % p, p) % p : 1; 29 | } 30 | 31 | int main() { 32 | re int T; scanf("%d", &T); while(T --) { 33 | re int n, m, p; scanf("%d%d%d", &n, &m, &p); 34 | printf("%lld\n", lucas(n + m, m, p)); 35 | } return 0; 36 | } -------------------------------------------------------------------------------- /算法例题/[CSP-S2019]/P5657-格雷码.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAXN=64; 4 | int n; 5 | unsigned long long k; 6 | int ans[MAXN+1]; 7 | unsigned long long mi2[MAXN+1]; 8 | void dfs(int i,int j,int dir){ 9 | if (i==0){ 10 | return; 11 | }else { 12 | if (dir==0){ 13 | if (k>=mi2[i-1]){ 14 | ans[i]=1; 15 | k=k-mi2[i-1]; 16 | dfs(i-1,k,1); 17 | }else { 18 | ans[i]=0; 19 | dfs(i-1,k,0); 20 | } 21 | }else { 22 | if (k>n>>k; 35 | mi2[0]=1; 36 | for(int i=1;i<=n;i++) mi2[i]=mi2[i-1]*2; 37 | dfs(n,k,0); 38 | for(int i=n;i>=1;i--) cout< 2 | 3 | void OS_Solaris_print() 4 | { 5 | printf("Solaris - Sun Microsystems\n"); 6 | } 7 | 8 | void OS_Windows_print() 9 | { 10 | printf("Windows - Microsoft\n"); 11 | 12 | } 13 | void OS_HP_UX_print() 14 | { 15 | printf("HP-UX - Hewlett Packard\n"); 16 | } 17 | 18 | int main() 19 | { 20 | int num; 21 | printf("Enter the number (1-3):\n"); 22 | scanf("%d",&num); 23 | switch(num) 24 | { 25 | case 1: 26 | OS_Solaris_print(); 27 | break; 28 | case 2: 29 | OS_Windows_print(); 30 | break; 31 | case 3: 32 | OS_HP_UX_print(); 33 | break; 34 | default: 35 | printf("Hmm! only 1-3 :-)\n"); 36 | break; 37 | } 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /算法模版/DS/normal-bit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 6 | 7 | typedef long long ll; 8 | 9 | const int N = 5e5 + 5; 10 | 11 | int n, m; ll c[N]; 12 | 13 | static inline void modify(int pos, ll val) { 14 | while(pos < N) { 15 | c[pos] += val; 16 | pos += pos & -pos; 17 | } return ; 18 | } 19 | 20 | static inline ll query(int pos) { 21 | ll res = 0; while(pos) { 22 | res += c[pos]; 23 | pos -= pos & -pos; 24 | } return res; 25 | } 26 | 27 | int main() { 28 | scanf("%d%d", &n, &m); re ll x; 29 | rep(i, 1, n) scanf("%lld", &x), modify(i, x); 30 | re int opt, l, r; re ll val; while(m --) { 31 | scanf("%d", &opt); if(opt == 1) 32 | scanf("%d%lld", &l, &val), 33 | modify(l, val); 34 | else scanf("%d%d", &l, &r), 35 | printf("%lld\n", query(r) - query(l - 1)); 36 | } return 0; 37 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之线性状态动态规划/P5858.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=5500; 6 | const int MAXW=5500; 7 | int n,w,s; 8 | long long a[MAXN+1]; 9 | long long totalNJD[MAXN+1][MAXW+1]; 10 | int main(){ 11 | scanf("%d %d %d",&n,&w,&s); 12 | for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 13 | for(int i=1;i<=n;i++) 14 | for(int j=1;j<=w;j++) { 15 | totalNJD[i][j]=LONG_LONG_MIN; 16 | } 17 | totalNJD[1][1]=1*a[1]; 18 | for(int i=2;i<=n;i++){ 19 | for(int j=1;j<=min(i,w);j++){ 20 | for(int k=max(j-1,1);k<=min(j+s-1,w);k++){ 21 | if (totalNJD[i-1][k]==LONG_LONG_MIN) break; 22 | long long t=totalNJD[i-1][k]+j*a[i]; 23 | if (t>totalNJD[i][j]) totalNJD[i][j]=t; 24 | else break; 25 | } 26 | } 27 | } 28 | long long ans=LONG_LONG_MIN; 29 | for(int j=1;j<=w;j++) ans=max(ans,totalNJD[n][j]); 30 | printf("%lld",ans); 31 | } 32 | -------------------------------------------------------------------------------- /算法模版/SA/kmp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define re register 5 | 6 | const int N = 1e6 + 5; 7 | 8 | char s[N], p[N]; 9 | int nxt[N], lens, lenp; 10 | 11 | static inline void compute() { 12 | nxt[0] = nxt[1] = 0; 13 | for(re int k = 0, i = 1; i < lenp; ++ i) { 14 | while(k && p[i] != p[k]) 15 | k = nxt[k]; 16 | if(p[i] == p[k]) ++ k; 17 | nxt[i + 1] = k; 18 | } return ; 19 | } 20 | 21 | static inline void compare() { 22 | for(re int i = 0, j = 0; j < lens; ++ j) { 23 | while(i && s[j] != p[i]) 24 | i = nxt[i]; 25 | if(s[j] == p[i]) ++ i; 26 | if(i == lenp) printf("%d\n", j - lenp + 2); 27 | } return; 28 | } 29 | 30 | static inline void output() { 31 | for(re int i = 1; i <= lenp; ++ i) 32 | printf("%d ", nxt[i]); 33 | return ; 34 | } 35 | 36 | int main() { 37 | scanf("%s%s", s, p), 38 | lens = strlen(s), lenp = strlen(p); 39 | compute(), compare(), output(); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之树与图上的动态规划/P1613.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=50; 7 | int n,m; 8 | bool can[MAXN+1][MAXN+1][64];//can[i][j][k]表示i到j是否有一条2^k次幂的路径 9 | int dis[MAXN+1][MAXN+1]; 10 | 11 | int main(){ 12 | cin>>n>>m; 13 | memset(dis,10,sizeof(dis)); 14 | for(int i=0;i>u>>v; 17 | dis[u][v]=1; 18 | can[u][v][0]=true; 19 | } 20 | 21 | for(int k=1;k<=64;k++) 22 | for(int i=1;i<=n;i++) 23 | for(int j=1;j<=n;j++) 24 | for(int o=1;o<=n;o++) 25 | if (can[i][o][k-1]&&can[o][j][k-1]) { 26 | can[i][j][k]=true; 27 | dis[i][j]=1; 28 | } 29 | //floyd求最短路径 30 | for(int k=1;k<=n;k++) 31 | for(int i=1;i<=n;i++) 32 | for(int j=1;j<=n;j++) 33 | if (dis[i][k]+dis[k][j] 2 | #include 3 | using namespace std; 4 | const int MAXN=100000; 5 | int a[MAXN+1]; 6 | int n; 7 | priority_queue maxheap; 8 | priority_queue,greater > minheap; 9 | 10 | int main(){ 11 | cin>>n; 12 | for(int i=1;i<=n;i++) cin>>a[i]; 13 | int smin=0; 14 | for(int i=1;i<=n;i++){ 15 | if (smin==0) { 16 | minheap.push(a[i]); 17 | smin++; 18 | }else { 19 | if (a[i]<=minheap.top()) { 20 | maxheap.push(a[i]); 21 | }else { 22 | minheap.push(a[i]); 23 | smin++; 24 | } 25 | } 26 | if (smin<((i+1)/2)){ 27 | minheap.push(maxheap.top()); 28 | smin++; 29 | maxheap.pop(); 30 | }else if (smin>((i+1)/2)){ 31 | maxheap.push(minheap.top()); 32 | smin--; 33 | minheap.pop(); 34 | } 35 | if (i%2>0) cout< 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 7 | 8 | typedef long long ll; 9 | 10 | const int N = 1e3 + 6; 11 | const int M = 2e4 + 6; 12 | 13 | int n, m, f[M], g[M], q[M]; 14 | 15 | static inline void upmax(int &a, int b) { 16 | if(a < b) a = b; return ; 17 | } 18 | 19 | int main() { 20 | scanf("%d%d", &n, &m); Rep(i, 0, n) { 21 | re int v, w, s; scanf("%d%d%d", &v, &w, &s); 22 | memcpy(g, f, sizeof(f)); Rep(j, 0, v) { 23 | re int h = 0, t = -1; 24 | for(re int k = j; k <= m; k += v) { 25 | if (h <= t && q[h] < k - s * v) ++ h; 26 | if (h <= t) upmax(f[k], g[q[h]] + (k - q[h]) / v * w); 27 | while (h <= t && g[q[t]] - (q[t] - j) / v * w <= g[k] - (k - j) / v * w) -- t; 28 | q[++ t] = k; 29 | } 30 | } 31 | } printf("%d\n", f[m]); return 0; 32 | } -------------------------------------------------------------------------------- /算法模版/DS/disjoint-set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define re register 4 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 5 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 6 | 7 | const int N = 1e4 + 5; 8 | 9 | int fa[N], sz[N], n, m; 10 | 11 | static inline void swap(int &a, int &b) { 12 | int t = a; a = b, b = t; return ; 13 | } 14 | 15 | int find(int x) { 16 | return fa[x] == x ? x : fa[x] = find(fa[x]); 17 | } 18 | 19 | static inline bool check(int x, int y){ 20 | return find(x) == find(y); 21 | } 22 | 23 | static inline void merge(int x, int y){ 24 | re int fx = find(x), fy = find(y); 25 | if(fx == fy) return ; 26 | if(sz[fx] > sz[fy]) swap(fx, fy); 27 | fa[fx] = fy, sz[fy] += sz[fx]; return ; 28 | } 29 | 30 | int main() { 31 | scanf("%d%d", &n, &m); 32 | rep(i, 1, n) sz[fa[i] = i] = 1; 33 | re int opt, x, y; while(m --) { 34 | scanf("%d%d%d", &opt, &x, &y); 35 | if(opt == 1) merge(x, y); 36 | else puts(check(x, y) ? "Y" : "N"); 37 | } return 0; 38 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题库]/p2052.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int MAXN=1000000; 5 | struct Edge{ 6 | int u,v,w; 7 | }; 8 | Edge edges[MAXN]; 9 | vector G[MAXN+1]; 10 | int parent[MAXN+1]; 11 | int size[MAXN+1]; 12 | int n; 13 | long long sum; 14 | 15 | void dfs(int u,int fa){ 16 | size[u]=1; 17 | parent[u]=fa; 18 | for(int k=0;k>n; 28 | for(int i=0;i>a>>b>>c; 31 | edges[i]={a,b,c}; 32 | G[a].push_back(b); 33 | G[b].push_back(a); 34 | } 35 | dfs(1,0); 36 | for(int i=0;i 2 | #include 3 | #include 4 | using namespace std; 5 | ifstream fin("ticket.in"); 6 | ofstream fout("ticket.out"); 7 | char yy[5]={'a','e','i','o','u'}; 8 | bool isyy[256]; 9 | char letter[26]; 10 | int L,C; 11 | char ans[15]; 12 | int num; 13 | void dfs(int dep,int k){ 14 | if (dep>=L){ 15 | int yycount=0; 16 | for(int i=0;i0&&yycount<=L-2) { 18 | num++; 19 | if (num<=25000) { 20 | for(int i=0;i>L>>C; 34 | for(int i=0;i>letter[i]; 35 | for(int i=0;i<5;i++) isyy[int(yy[i])]=true; 36 | sort(letter,letter+C); 37 | dfs(0,0); 38 | system("pause"); 39 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]二叉堆与ST表/P4053.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=150000; 6 | struct Task{ 7 | int t1; 8 | int t2; 9 | bool operator<(const Task other)const{ 10 | return t2 heap; 15 | int sumt; 16 | int n,ans; 17 | 18 | int main(){ 19 | cin>>n; 20 | for(int i=0;i>tasks[i].t1>>tasks[i].t2; 22 | } 23 | sort(tasks,tasks+n); 24 | sumt=0; 25 | ans=0; 26 | for(int i=0;i 3 | #include 4 | using namespace std; 5 | ifstream fin("aniv.in"); 6 | ofstream fout("aniv.out"); 7 | 8 | const int MAXN=6000; 9 | int happy[MAXN+1]; 10 | vector graph[MAXN+1]; 11 | int dp_max[MAXN+1][2]; 12 | int n; 13 | int parent[MAXN+1]; 14 | 15 | void dp(int x){ 16 | int s=graph[x].size(); 17 | int s0=0,s1=0; 18 | for(int k=0;k>n; 29 | for(int i=1;i<=n;i++) fin>>happy[i]; 30 | int l,k; 31 | fin>>l>>k; 32 | while(l>0&&k>0){ 33 | graph[k].push_back(l); 34 | parent[l]=k; 35 | fin>>l>>k; 36 | } 37 | 38 | int cur=1; 39 | while(parent[cur]>0) cur=parent[cur]; 40 | int root=cur; 41 | dp(root); 42 | fout< 3 | using namespace std; 4 | ifstream fin("TREE.in"); 5 | ofstream fout("TREE.out"); 6 | 7 | const int MAXN=30; 8 | long dp_max[MAXN+1][MAXN+1]; 9 | int dp_path[MAXN+1][MAXN+1]; 10 | 11 | int a[MAXN+1]; 12 | int n; 13 | 14 | long dp(int i,int j){ 15 | if (dp_max[i][j]>0) return dp_max[i][j]; 16 | if (i>j) return 1; 17 | if (i==j) return a[i]; 18 | for(int r=i;r<=j;r++){ 19 | long t=dp(i,r-1)*dp(r+1,j)+a[r]; 20 | if (t>dp_max[i][j]){ 21 | dp_max[i][j]=t; 22 | dp_path[i][j]=r; 23 | } 24 | } 25 | return dp_max[i][j]; 26 | } 27 | void root_first_visit(int i,int j){ 28 | if (i>j) return; 29 | if (i==j) fout<>n; 39 | for(int i=1;i<=n;i++) fin>>a[i]; 40 | fout< 3 | using namespace std; 4 | ifstream fin("transfer.in"); 5 | ofstream fout("transfer.out"); 6 | 7 | const int MAXN=50000; 8 | int factorSum[MAXN+1]; 9 | int maxLen[MAXN+1],secondMaxLen[MAXN+1];//maxLen[i]表示以i为根的子树中, 10 | //i到叶子结点的最长路径,secondMaxLen[i]是i到叶子结点的次长路径 11 | 12 | int n; 13 | 14 | int main(){ 15 | fin>>n; 16 | for(int i=1;i<=n;i++) 17 | for(int j=2;j<=n/i;j++) 18 | factorSum[i*j]+=i; 19 | for(int i=n;i>=1;i--){//大的数总是挂在小的数下,所以从大到小遍历计算 20 | if (factorSum[i]maxLen[p]){ 23 | secondMaxLen[p]=maxLen[p]; 24 | maxLen[p]=maxLen[i]+1; 25 | }else if (maxLen[i]+1>secondMaxLen[p]){ 26 | secondMaxLen[p]=maxLen[i]+1; 27 | } 28 | } 29 | } 30 | int ans=0; 31 | for(int i=n;i>=1;i--){ 32 | if (maxLen[i]+secondMaxLen[i]>ans) ans=maxLen[i]+secondMaxLen[i]; 33 | } 34 | fout<=start;i--){ 18 | printf("%d ",matrix[endY*rows+i]); 19 | } 20 | 21 | for(int i=endY-1;i>start;i--){ 22 | printf("%d ",matrix[i*rows+start]); 23 | } 24 | } 25 | 26 | void print_matrix(int *matrix,int rows,int cols){ 27 | if(matrix==NULL) return ; 28 | if(rows<=0 || cols<=0) return; 29 | 30 | int start = 0; 31 | while(start*2 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=10000; 6 | const int MAXK=10000; 7 | 8 | int p[MAXK],t[MAXK]; 9 | int dp[MAXN+2]; 10 | bool calculted[MAXN+2]; 11 | vector taskTree[MAXN+1]; 12 | 13 | int n,k; 14 | void tree_dp(int i){ 15 | if (i>n||calculted[i]) return; 16 | int size=taskTree[i].size(); 17 | if (size==0){ 18 | tree_dp(i+1); 19 | dp[i]=dp[i+1]; 20 | }else { 21 | dp[i]=n; 22 | for(int j=0;j>n>>k; 33 | for(int i=0;i>p[i]>>t[i]; 35 | taskTree[p[i]].push_back(i); 36 | } 37 | 38 | fill(calculted,calculted+n+1,false); 39 | tree_dp(1); 40 | cout< 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | 7 | const int MAXN = 1e6 + 5; 8 | int n, k, a[MAXN]; 9 | struct NODE{ int val, pos; }; 10 | std::deque q; 11 | 12 | void MAX(){ 13 | q.clear(); rep(i, 1, n){ 14 | while(!q.empty() && q.back().val <= a[i]) 15 | q.pop_back(); 16 | q.push_back((NODE){a[i], i}); 17 | while(q.front().pos <= i - k) 18 | q.pop_front(); 19 | if(i >= k) printf("%d ", q.front().val); 20 | } puts(""); return ; 21 | } 22 | 23 | void MIN(){ 24 | q.clear(); rep(i, 1, n){ 25 | while(!q.empty() && q.back().val >= a[i]) 26 | q.pop_back(); 27 | q.push_back((NODE){a[i], i}); 28 | while(q.front().pos <= i - k) 29 | q.pop_front(); 30 | if(i >= k) printf("%d ", q.front().val); 31 | } puts(""); return ; 32 | } 33 | 34 | int main(){ 35 | scanf("%d%d",&n,&k); 36 | rep(i, 1, n) scanf("%d",&a[i]); 37 | MIN(), MAX(); return 0; 38 | } 39 | -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之区间与环形动态规划/P1220.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int MAXN=50; 5 | int n,c; 6 | int w[MAXN+1],p[MAXN+1]; 7 | int sumw[MAXN+1]; 8 | int dp[MAXN+1][MAXN+1][2];//dp[i][j]表示关掉区间[i,j]里的灯时,所有的灯耗费的电量 9 | 10 | int main(){ 11 | cin>>n>>c; 12 | for(int i=1;i<=n;i++) { 13 | cin>>p[i]>>w[i]; 14 | sumw[i]=sumw[i-1]+w[i]; 15 | } 16 | for(int i=1;i<=n;i++){ 17 | int t=abs(p[i]-p[c]); 18 | dp[i][i][0]=t*sumw[n]; 19 | dp[i][i][1]=t*sumw[n]; 20 | } 21 | 22 | for(int len=2;len<=n;len++){ 23 | for(int i=1;i<=n-len+1;i++){ 24 | int j=i+len-1; 25 | int v1=dp[i+1][j][0]+(p[i+1]-p[i])*(sumw[i]+sumw[n]-sumw[j]); 26 | int v2=dp[i+1][j][1]+(p[j]-p[i])*(sumw[i]+sumw[n]-sumw[j]); 27 | dp[i][j][0]=min(v1,v2); 28 | v1=dp[i][j-1][0]+(p[j]-p[i])*(sumw[i-1]+sumw[n]-sumw[j-1]); 29 | v2=dp[i][j-1][1]+(p[j]-p[j-1])*(sumw[i-1]+sumw[n]-sumw[j-1]); 30 | dp[i][j][1]=min(v1,v2); 31 | } 32 | } 33 | cout< 2 | #include 3 | 4 | typedef long long ll; 5 | #define re register 6 | #define rep(i, a, b) for(re int (i) = (a); (i) <= (b); ++ (i)) 7 | #define mst(a, b) memset((a), (b), sizeof((a))) 8 | 9 | using namespace std; 10 | 11 | const int N = 25; 12 | ll a, b, f[N][N], cnt, p[N]; 13 | template 14 | extern inline T abs(T x){ return x < 0 ? -x : x; } 15 | 16 | inline ll dfs(int pos,int lst,bool lim1,bool lim2) { 17 | if(!pos) return 1; 18 | if(!lim2 && !lim1 && f[pos][lst] != -1) 19 | return f[pos][lst]; 20 | int op, up = lim1 ? p[pos] : 9; 21 | ll tmp = 0; rep(i, 0, up){ 22 | if(abs(i - lst) < 2) continue; 23 | op = i; if(lim2 && !i) op = -2; 24 | tmp += dfs(pos - 1, op, (lim1) && (i == up), (op == -2)); 25 | } if(!lim1 && !lim2) f[pos][lst] = tmp; 26 | return tmp; 27 | } 28 | inline ll solve(ll x) { 29 | cnt = 0; while(x) p[++ cnt] = x % 10, x /= 10; 30 | return dfs(cnt, -2, 1, 1); 31 | } 32 | int main() { 33 | scanf("%d%d", &a, &b); mst(f, -1); 34 | printf("%lld\n",solve(b) - solve(a - 1)); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /算法例题/[基本算法]动态规划/missile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("missile.in"); 4 | ofstream fout("missile.out"); 5 | const int MAXN=1000; 6 | int n; 7 | int high[MAXN]; 8 | int dp[MAXN];//dp[i] 表示前 i 枚导弹,在第 i 枚被拦截的前提下,能拦截的最大导弹数 9 | int ans1,ans2; 10 | int minHigh[MAXN];//minHigh[k] 记录第 k 套系统拦截导弹的最低高度 11 | 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>high[i]; 15 | //动规计算出 dp[i] 16 | for(int i=0;i=high[i]) dp[i]=max(dp[i],dp[k]+1); 20 | } 21 | //找出最大的 dp[i] 22 | for(int i=0;ians1) ans1=dp[i]; 24 | 25 | //计算需要多少套拦截系统 26 | int ans2=1; 27 | minHigh[0]=high[0]; 28 | 29 | for(int i=1;i 2 | #include 3 | 4 | using namespace std; 5 | 6 | const int MAXN=20; 7 | int fz[MAXN][MAXN]; 8 | int n; 9 | 10 | int main(){ 11 | cin>>n; 12 | int c=0; 13 | bool dir=1; 14 | for(int b=n-1;b>=-(n-1);b--){ 15 | switch (dir){ 16 | case 0: 17 | for(int x=0;x=0&&y=0;x--){ 27 | int y=x+b; 28 | if (y>=0&&y 2 | using namespace std; 3 | string s; 4 | int m,d; 5 | int monday[13]={0,31,28,31,30,31,60,31,31,30,31,30,31}; 6 | int main(){ 7 | cin>>s; 8 | m=(s[0]-'0')*10+(s[1]-'0'); 9 | d=(s[3]-'0')*10+(s[4]-'0'); 10 | int tl=s[1]-'0'; 11 | int th=s[0]-'0'; 12 | if (d>31){ 13 | if (m>12) cout<<2; 14 | else if (m>0) cout<<1; 15 | else cout<<2; 16 | }else if (d>28){ 17 | if (m>12) { 18 | if (d<=monday[tl]) cout<<1; 19 | else if (tl+10<=12&&d<=monday[tl+10]) cout<<1; 20 | else if (th*10+1<=12&&d<=monday[th*10+1]) cout<<1; 21 | else if (th*10+2<=12&&d<=monday[th*10+2]) cout<<1; 22 | else cout<<2; 23 | } 24 | else if (m>0) { 25 | if (d>monday[m]) cout<<1; 26 | else cout<<0; 27 | } 28 | else cout<<1; 29 | 30 | }else if (d>0){ 31 | if (m>12) cout<<1; 32 | else if (m>0) cout<<0; 33 | else cout<<1; 34 | }else { 35 | if (m>12) cout<<2; 36 | else if (m>0) cout<<1; 37 | else cout<<2; 38 | } 39 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之线性状态动态规划/P1020.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAXN=100000; 4 | int n; 5 | int high[MAXN]; 6 | int dp[MAXN];//dp[i] 表示前 i 枚导弹,在第 i 枚被拦截的前提下,能拦截的最大导弹数 7 | int ans1,ans2; 8 | int minHigh[MAXN];//minHigh[k] 记录第 k 套系统拦截导弹的最低高度 9 | 10 | int main(){ 11 | int i=0; 12 | int a; 13 | while(cin>>a){ 14 | high[i]=a; 15 | i++; 16 | } 17 | n=i; 18 | //动规计算出 dp[i] 19 | for(int i=0;i=high[i]) dp[i]=max(dp[i],dp[k]+1); 23 | } 24 | //找出最大的 dp[i] 25 | for(int i=0;ians1) ans1=dp[i]; 27 | 28 | //计算需要多少套拦截系统 29 | int ans2=1; 30 | minHigh[0]=high[0]; 31 | 32 | for(int i=1;i 2 | 3 | #define re register 4 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 5 | #define Down(i, a) for(re int i = (a) - 1; ~i; -- i) 6 | 7 | const int N = 1e5 + 5; 8 | int n, cnt[4][0x100], b[N], a[N]; 9 | 10 | static inline void sort() { 11 | Rep(i, 0, n) 12 | ++ cnt[0][(a[i] ) & 0xff], 13 | ++ cnt[1][(a[i] >> 8) & 0xff], 14 | ++ cnt[2][(a[i] >> 16) & 0xff], 15 | ++ cnt[3][(a[i] >> 24) & 0xff]; 16 | 17 | Rep(i, 1, 0x100) 18 | cnt[0][i] += cnt[0][i - 1], 19 | cnt[1][i] += cnt[1][i - 1], 20 | cnt[2][i] += cnt[2][i - 1], 21 | cnt[3][i] += cnt[3][i - 1]; 22 | 23 | Down(i, n) 24 | b[-- cnt[0][(a[i] ) & 0xff]] = a[i]; 25 | Down(i, n) 26 | a[-- cnt[1][(b[i] >> 8) & 0xff]] = b[i]; 27 | Down(i, n) 28 | b[-- cnt[2][(a[i] >> 16) & 0xff]] = a[i]; 29 | Down(i, n) 30 | a[-- cnt[3][(b[i] >> 24) & 0xff]] = b[i]; 31 | } 32 | 33 | int main() { 34 | scanf("%d", &n); 35 | Rep(i, 0, n) scanf("%d", &a[i]); 36 | sort(); 37 | Rep(i, 0, n) printf("%d ", a[i]); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /算法学习/Algorithms In Open Source/YYCache.md: -------------------------------------------------------------------------------- 1 | 2 | ## YYCache 3 | 4 | [YYCache](https://github.com/ibireme/YYCache.git) 是 iOS 系统上一套线程安全的 `Key-Value` 缓存实现,使用 `Objective-C` 语言实现。`YYCache` 使用 `双向链表队列+hash表结构` 实现。 5 | 6 | ### 用到的算法介绍 7 | 8 | 先来看一下它的数据结构: 9 | 10 | ``` 11 | // 这是一个节点的结构 12 | @interface _YYLinkedMapNode : NSObject { 13 | @package 14 | __unsafe_unretained _YYLinkedMapNode *_prev; // retained by dic 15 | __unsafe_unretained _YYLinkedMapNode *_next; // retained by dic 16 | id _key; 17 | id _value; 18 | NSUInteger _cost; 19 | NSTimeInterval _time; 20 | } 21 | ``` 22 | 23 | 这里定义了一个双向链表结构,`_prev`,`_next`分别指向前缀节点和后缀节点。 24 | 25 | ``` 26 | @interface _YYLinkedMap : NSObject { 27 | @package 28 | CFMutableDictionaryRef _dic; // do not set object directly 29 | NSUInteger _totalCost; 30 | NSUInteger _totalCount; 31 | _YYLinkedMapNode *_head; // MRU, do not change it directly 32 | _YYLinkedMapNode *_tail; // LRU, do not change it directly 33 | BOOL _releaseOnMainThread; 34 | BOOL _releaseAsynchronously; 35 | } 36 | ``` 37 | _dic 就是存储缓存节点的hash结构 38 | _head 指向链表的头部,_tail指向链表的尾部,组成一个队列结构 39 | 40 | 41 | -------------------------------------------------------------------------------- /算法例题/[提高训练]动态规划之数位DP/test.cpp: -------------------------------------------------------------------------------- 1 | //#1018. 「一本通 5.3 例 2」数字游戏 2 | #include 3 | using namespace std; 4 | ifstream fin("test.in"); 5 | ofstream fout("test.out"); 6 | 7 | const int MAXLEVEL=31; 8 | int f[MAXLEVEL+1][10];//f[i][j] 表示高度为i的完全10叉树中当根结点为j时,由根结点到叶结点的路径所组成的数是不降数的个数 9 | int a,b; 10 | 11 | void dp(){ 12 | for(int i=0;i<=9;i++) f[0][i]=1; 13 | for(int i=1;i<=MAXLEVEL;i++) 14 | for(int j=0;j<=9;j++){ 15 | for(int k=j;k<=9;k++) f[i][j]+=f[i-1][k]; 16 | } 17 | } 18 | 19 | int calc(int x){ 20 | int t[MAXLEVEL+1]={0}; 21 | int k=0; 22 | while(x>0){ 23 | int d=x % 10; 24 | t[k]=d; 25 | k++; 26 | x= x / 10; 27 | } 28 | int tot=0,ans=0; 29 | int i=max(k-1,0); 30 | for(;i>=0;i--){ 31 | int d=t[i]; 32 | if (d>a) { 43 | fin>>b; 44 | int n1=calc(a-1); 45 | int n2=calc(b); 46 | fout< 2 | #include 3 | #define ll long long 4 | using namespace std; 5 | const int MAXN=40; 6 | const long MAXK=1200000; 7 | ll values[MAXK]; 8 | int vcount; 9 | int n; 10 | ll m; 11 | ll price[MAXN+1]; 12 | ll ans=0; 13 | void lsearch(int pos,ll val){ 14 | if (val>0&&val<=m){ 15 | ans++; 16 | values[vcount]=val; 17 | vcount++; 18 | } 19 | if (val>m) return; 20 | for(int i=pos+1;i<=n/2;i++){ 21 | if (val+price[i]>m) break; 22 | lsearch(i,val+price[i]); 23 | } 24 | } 25 | void rsearch(int pos,ll val){ 26 | if (val>0&&val<=m){ 27 | ans++; 28 | int i=upper_bound(values,values+vcount,m-val)-values; 29 | if (i>=0) ans+=i; 30 | } 31 | if (val>m) return; 32 | for(int i=pos+1;i<=n;i++){ 33 | if (val+price[i]>m) break; 34 | rsearch(i,val+price[i]); 35 | } 36 | } 37 | int main(){ 38 | cin>>n>>m; 39 | for(int i=1;i<=n;i++) cin>>price[i]; 40 | sort(price,price+n+1); 41 | lsearch(0,0); 42 | sort(values,values+vcount); 43 | rsearch(n/2,0); 44 | ans++; 45 | cout< '9'){//字母 13 | if(tmp > max){ 14 | max = tmp; 15 | start = mid; 16 | } 17 | tmp = 0; 18 | }else{//数字 19 | if (tmp == 0){//发现数字 20 | mid = end; 21 | } 22 | tmp++; 23 | } 24 | end++; 25 | } 26 | 27 | //修改已数字结尾的bug 28 | if(tmp > max){ 29 | max = tmp; 30 | start = mid; 31 | } 32 | 33 | //copy 34 | int i=0; 35 | while(i 2 | #include 3 | #define re register 4 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 5 | typedef long long ll; 6 | const int p[] = { 2, 3, 5, 7, 17, 19, 61 }; 7 | ll mul(ll a, ll b, ll p) { 8 | ll w = (long double)a * b / p + 0.5, r = a * b - w * p; 9 | assert((__int128)w * p + r == (__int128)a * b); 10 | return r < 0 ? r + p : r; 11 | } 12 | ll qpow(ll a, ll b, ll p) { 13 | ll res = 1; while(b) { 14 | if (b & 1) res = mul(res, a, p); 15 | a = mul(a, a, p), b >>= 1; 16 | } return res; 17 | } 18 | bool mr(ll n) { 19 | if (n == 1) return 0; 20 | Rep(i, 0, 7) if (!(n % p[i])) return n == p[i]; 21 | ll r = n - 1, x, y; int t = 0; 22 | while (!(r & 1)) r >>= 1, ++t; 23 | Rep(i, 2, 7) { 24 | x = qpow(p[i], r, n); 25 | for (re int j = 0; j < t && x > 1; ++j) { 26 | y = mul(x, x, n); 27 | if (y == 1 && x != n - 1) 28 | return 0; 29 | x = y; 30 | } if (x != 1) return 0; 31 | } return 1; 32 | } 33 | int main() { 34 | ll n; while (~scanf("%lld", &n)) 35 | puts(mr(n) ? "Y" : "N"); 36 | return 0; 37 | } -------------------------------------------------------------------------------- /算法例题/[提高训练]动态规划之树型DP/apple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | ifstream fin("apple.in"); 7 | ofstream fout("apple.out"); 8 | const int MAXN=100; 9 | struct node 10 | { 11 | int next; 12 | int applenum; 13 | }; 14 | 15 | vector graph[MAXN+1]; 16 | int parent[MAXN+1]; 17 | int dp_max[MAXN+1][MAXN+1]; 18 | int n,q; 19 | void dp(int x){ 20 | int s=graph[x].size(); 21 | for(int k=0;k0;w--) 28 | for(int v=w-1;v>=0;v--) 29 | dp_max[x][w]=max(dp_max[x][w],dp_max[x][w-v-1]+dp_max[y][v]+n.applenum); 30 | } 31 | } 32 | } 33 | 34 | int main(){ 35 | fin>>n>>q; 36 | for(int i=1;i<=n-1;i++){ 37 | int a,b,c; 38 | fin>>a>>b>>c; 39 | node n1={b,c}; 40 | graph[a].push_back(n1); 41 | node n2={a,c}; 42 | graph[b].push_back(n2); 43 | } 44 | parent[1]=0; 45 | dp(1); 46 | //for(int i=0;i<=q;i++) cout< 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 7 | 8 | typedef long long ll; 9 | 10 | const int mod = 1e9 + 7; 11 | 12 | static inline void up(ll &x, ll y) { 13 | x = (x + y) % mod; 14 | } 15 | 16 | const int n = 100 + 5; 17 | 18 | struct mat { 19 | ll a[n][n]; 20 | friend mat operator * (const mat x, const mat y) { 21 | mat z; memset(z.a, 0, sizeof(z.a)); 22 | Rep(i, 0, n) Rep(j, 0, n) Rep(k, 0, n) 23 | up(z.a[i][j], x.a[i][k] * y.a[k][j]); 24 | return z; 25 | } 26 | }; 27 | 28 | mat qpow(mat x, ll b) { 29 | mat res; Rep(i, 0, n) Rep(j, 0, n) res.a[i][j] = 0; 30 | Rep(i, 0, n) res.a[i][i] = 1; while(b) { 31 | if(b & 1) res = res * x; x = x * x, b >>= 1; 32 | } return res; 33 | } 34 | 35 | int main() { 36 | ll N, K; scanf("%lld%lld", &N, &K); mat base; 37 | Rep(i, 0, N) Rep(j, 0, N) scanf("%lld", &base.a[i][j]); 38 | mat ans = qpow(base, K); Rep(i, 0, N) { 39 | Rep(j, 0, N) printf("%lld ", ans.a[i][j]); 40 | putchar('\n'); 41 | } return 0; 42 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]动态规划之线性状态动态规划/p4933_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=1000; 7 | const int MAXV=20000; 8 | int n; 9 | int high[MAXV+1]; 10 | int solutions[MAXN][MAXV*2]; 11 | vector gc[MAXN]; 12 | 13 | int main(){ 14 | cin>>n; 15 | for(int i=0;i>high[i]; 17 | } 18 | for(int i=1;i 2 | using namespace std; 3 | struct node 4 | { 5 | int id; 6 | node *prev,*next; 7 | }; 8 | 9 | int n,m; 10 | node *head; 11 | node *last; 12 | node *cur; 13 | 14 | int main(){ 15 | cin>>n>>m; 16 | head=new(node); 17 | head->next=NULL; 18 | head->prev=NULL; 19 | last=head; 20 | for(int i=1;i<=n;i++){ 21 | cur=new(node); 22 | cur->id=i; 23 | cur->next=NULL; 24 | cur->prev=NULL; 25 | last->next=cur; 26 | cur->prev=last; 27 | last=cur; 28 | } 29 | node *p=head->next; 30 | 31 | int i=0; 32 | int d=0; 33 | while(p!=NULL&&p!=head){ 34 | i++; 35 | if (i==m){ 36 | if (p->prev!=NULL) p->prev->next=p->next; 37 | if (p->next!=NULL) p->next->prev=p->prev; 38 | i=0; 39 | } 40 | if (d==0){ 41 | if (p->next==NULL){ 42 | d=1; 43 | p=p->prev; 44 | }else p=p->next; 45 | }else { 46 | if (p->prev==head){ 47 | d=0; 48 | p=p->next; 49 | }else p=p->prev; 50 | } 51 | } 52 | cout<next->id; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /算法例题/[基本算法]深度优先搜索/meeting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("meeting.in"); 4 | ofstream fout("meeting.out"); 5 | 6 | const int MAXN=16; 7 | int g_bls[MAXN+1][MAXN+1]; 8 | int g_als[MAXN+1][MAXN+1]; 9 | 10 | bool times[150010]; 11 | 12 | int n,m; 13 | int min_time=150010; 14 | 15 | void dfs_bls(int dep,int i,int time){ 16 | if (i==n){ 17 | times[time]=true; 18 | }else if (dep>n-1) return; 19 | else { 20 | for(int j=1;j<=n;j++){ 21 | if (g_bls[i][j]>0) dfs_bls(dep+1,j,time+g_bls[i][j]); 22 | } 23 | } 24 | } 25 | 26 | void dfs_als(int dep,int i,int time){ 27 | if (i==n){ 28 | if (times[time]&&timen-1) return; 32 | else { 33 | for(int j=1;j<=n;j++){ 34 | if (g_als[i][j]>0) dfs_als(dep+1,j,time+g_als[i][j]); 35 | } 36 | } 37 | } 38 | int main(){ 39 | fin>>n>>m; 40 | for(int i=0;i>a>>b>>c>>d; 43 | g_bls[a][b]=c; 44 | g_als[a][b]=d; 45 | } 46 | dfs_bls(1,1,0); 47 | dfs_als(1,1,0); 48 | if (min_time==150010) fout<<"IMPOSSIBLE"; 49 | else fout< 2 | #include 3 | 4 | using namespace std; 5 | const int MAXM=12; 6 | const int MAXN=12; 7 | const int MAXS=4095;//2^12-1 8 | const int K=100000000; 9 | int dp[MAXM+1][MAXS+1]; 10 | int flag[MAXM+1]; 11 | int m,n; 12 | int lastS; 13 | bool can(int s,int i){ 14 | if (s&(s>>1)) return false; 15 | else if ((~flag[i])&s) return false; 16 | else return true; 17 | } 18 | bool conflict(int s1,int s2){ 19 | if (s1&s2) return true; 20 | return false; 21 | } 22 | 23 | int main(){ 24 | cin>>m>>n; 25 | lastS=pow(2,n)-1; 26 | for(int i=1;i<=m;i++){ 27 | int mi=1; 28 | for(int j=1;j<=n;j++){ 29 | int c; 30 | cin>>c; 31 | flag[i]+=mi*c; 32 | mi=mi*2; 33 | } 34 | } 35 | dp[0][0]=1; 36 | for(int i=1;i<=m;i++){ 37 | for(int s1=0;s1<=lastS;s1++){ 38 | if (!can(s1,i)) continue; 39 | for(int s2=0;s2<=lastS;s2++){ 40 | if (!can(s2,i-1)) continue; 41 | if (!conflict(s1,s2)) dp[i][s1]=(dp[i][s1]+dp[i-1][s2]) % K; 42 | } 43 | } 44 | } 45 | int ans=0; 46 | for(int s=0;s<=lastS;s++) ans=(ans+dp[m][s])%K; 47 | cout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=210; 7 | const int MAXQ=50000; 8 | const int INF=0x3fffffff; 9 | 10 | int n,m,q; 11 | int bt[MAXN]; 12 | int dist[MAXN][MAXN]; 13 | //对floyd算法进行改造,每次通过当前已重建的村庄u进行松弛操作 14 | void update(int u){ 15 | for(int i=0;it||bt[y]>t) printf("%d\n",-1); 36 | else { 37 | while(bt[now]<=t&&now 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("separation.in"); 7 | ofstream fout("separation.out"); 8 | const int MAXN=300; 9 | int dp_max[MAXN+1][MAXN+1]; 10 | int dp_path[MAXN+1][MAXN+1]; 11 | 12 | int a[MAXN+1]; 13 | int n; 14 | vector tree[MAXN]; 15 | 16 | void search(int i,int j,int deep){ 17 | if (i>=j) return; 18 | else { 19 | int k=dp_path[i][j]; 20 | tree[deep].push_back(k); 21 | search(i,k,deep+1); 22 | search(k+1,j,deep+1); 23 | } 24 | } 25 | int main(){ 26 | fin>>n; 27 | for(int i=1;i<=n;i++) fin>>a[i]; 28 | 29 | for(int len=2;len<=n;len++){ 30 | for(int i=1;i<=n-len+1;i++){ 31 | int j=i+len-1; 32 | for(int k=i;kdp_max[i][j]){ 35 | dp_max[i][j]=t; 36 | dp_path[i][j]=k; 37 | } 38 | } 39 | } 40 | } 41 | fout< 2 | using namespace std; 3 | ifstream fin("mas.in"); 4 | ofstream fout("mas.out"); 5 | 6 | int u; 7 | bool used[10]; 8 | int ans[10]; 9 | int sum[10][2]; 10 | int pailei[10][10]; 11 | 12 | void dfs(int i){ 13 | if (i>=u){ 14 | bool can=true; 15 | for(int j=0;j>u; 44 | for(int i=0;i>sum[i][0]>>sum[i][1]; 46 | for(int j=0;j>pailei[i][j]; 47 | } 48 | dfs(0); 49 | system("pause"); 50 | } -------------------------------------------------------------------------------- /算法例题/[基本数据结构]并查集及其应用/relation.cpp: -------------------------------------------------------------------------------- 1 | //#35. 亲戚 2 | #include 3 | using namespace std; 4 | 5 | const int MAXN=20000; 6 | struct union_find_set{ 7 | int father[MAXN+1]; 8 | void make_set(){ 9 | for(int i=1;i<=MAXN;i++) father[i]=i; 10 | } 11 | int find_set(int x){ 12 | while(father[x]!=x) x=father[x]; 13 | return x; 14 | } 15 | void union_set(int x,int y){ 16 | int hx=find_set(x); 17 | int hy=find_set(y); 18 | while(father[y]!=y){ 19 | int p=father[y]; 20 | father[y]=hx; 21 | y=p; 22 | } 23 | father[hy]=hx; 24 | } 25 | }; 26 | 27 | union_find_set ufs; 28 | void getd(int &x){ 29 | char c; 30 | for(c=getc(stdin);c<'0'||c>'9';c=getc(stdin)); 31 | 32 | for(x=0;c>='0'&&c<='9';c=getc(stdin)) 33 | x=x*10+c-'0'; 34 | } 35 | int n,m,q; 36 | int main(){ 37 | getd(n);getd(m); 38 | ufs.make_set(); 39 | for(long i=0;i 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=5500; 7 | const int MAXW=5500; 8 | int n,w,s; 9 | long long a[MAXN+1]; 10 | long long totalNJD[MAXN+1][MAXW+1]; 11 | long long val[MAXW+1]; 12 | int pos[MAXW+1]; 13 | 14 | int main(){ 15 | scanf("%d %d %d",&n,&w,&s); 16 | for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 17 | for(int i=1;i<=n;i++) 18 | for(int j=1;j<=w;j++) { 19 | totalNJD[i][j]=LONG_LONG_MIN; 20 | } 21 | totalNJD[1][1]=1*a[1]; 22 | for(int i=2;i<=n;i++){ 23 | int left=1,right=1; 24 | int last=min(i-1,w); 25 | val[left]=totalNJD[i-1][last]; 26 | pos[left]=last; 27 | for(int j=min(i,w);j;j--){ 28 | while(pos[left]>j+s-1&&left<=right) left++; 29 | if (j>1){ 30 | while(val[right] 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=500000; 6 | int n,m,r; 7 | vector tree[MAXN+1]; 8 | int f[MAXN+1][21]; 9 | int deep[MAXN+1]; 10 | 11 | void pre(int u,int fa){ 12 | deep[u]=deep[fa]+1; 13 | f[u][0]=fa; 14 | for(int k=0;k=0;i--) 24 | if (deep[f[x][i]]>=deep[y]) x=f[x][i]; 25 | if (x==y) return x; 26 | for(int i=20;i>=0;i--){ 27 | if (f[x][i]!=f[y][i]){ 28 | x=f[x][i]; 29 | y=f[y][i]; 30 | } 31 | } 32 | return f[x][0]; 33 | } 34 | int main(){ 35 | scanf("%d %d %d",&n,&m,&r); 36 | for(int i=1;i 3 | #include 4 | using namespace std; 5 | ifstream fin("zoo.in"); 6 | ofstream fout("zoo.out"); 7 | 8 | const int MAXN=10000; 9 | const int MAXC=50000; 10 | const int INF=0x7fffffff; 11 | 12 | int dp[MAXN+1][32]; 13 | int num[MAXN+1][32]; 14 | int e,f,l; 15 | int fflag,lflag; 16 | int n,c; 17 | 18 | int main(){ 19 | fin>>n>>c; 20 | for(int i=1;i<=c;i++){ 21 | fin>>e>>f>>l; 22 | fflag=0;lflag=0; 23 | for(int j=0;j>x; 26 | x=(x+n-e)%n; 27 | fflag+=1<>y; 32 | y=(y+n-e)%n; 33 | lflag+=1< 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 7 | 8 | typedef long long ll; 9 | 10 | const int M = 1e6 + 5; 11 | const int N = 2e5 + 5; 12 | 13 | struct EDGE { int u, v, w; }e[M]; 14 | 15 | static inline bool cmp(EDGE A, EDGE B) { 16 | return A.w < B.w; 17 | } 18 | 19 | static inline void swap(int &a, int &b) { 20 | re int t = a; a = b, b = t; return ; 21 | } 22 | 23 | int n, m, fa[N], sz[N]; ll ans = 0; 24 | 25 | int find(int x) { 26 | return fa[x] == x ? x : fa[x] = find(fa[x]); 27 | } 28 | 29 | bool merge(int x, int y) { 30 | re int fx = find(x), fy = find(y); 31 | if(fx == fy) return false; 32 | if(sz[fx] > sz[fy]) swap(fx, fy); 33 | fa[fx] = fy, sz[fy] += sz[fx]; return true; 34 | } 35 | 36 | int main() { 37 | scanf("%d%d", &n, &m); 38 | rep(i, 1, m) scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w); 39 | rep(i, 1, n) sz[fa[i] = i] = 1; std::sort(e + 1, e + m + 1, cmp); 40 | re int cnt = 0; rep(i, 1, m) { 41 | if(!merge(e[i].u, e[i].v)) 42 | continue; 43 | ++ cnt; ans += e[i].w; 44 | if(cnt == n - 1) break; 45 | } if(cnt != n - 1) puts("orz"); 46 | else printf("%lld\n", ans); return 0; 47 | } -------------------------------------------------------------------------------- /算法例题/[基本算法]阶段测试一/whatbase.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | ifstream fin("whatbase.in"); 5 | ofstream fout("whatbase.out"); 6 | 7 | int k,a,b; 8 | 9 | long long ndigit(int m,int n){ 10 | long long ret=0; 11 | int p=m; 12 | int mi=1; 13 | while(p>0){ 14 | int q=p%10; 15 | ret+=q*mi; 16 | p=p/10; 17 | mi=mi*n; 18 | } 19 | return ret; 20 | } 21 | 22 | int main(){ 23 | fin>>k; 24 | for(int i=0;i>a>>b; 26 | for(int x=10;x<=15000;x++){ 27 | long long m1=ndigit(a,x); 28 | int left,right; 29 | if (a>b){ 30 | left=x+1; 31 | right=15000; 32 | }else { 33 | left=10; 34 | right=x; 35 | } 36 | bool find=false; 37 | while(left<=right){ 38 | int y=(left+right)/2; 39 | long long m2=ndigit(b,y); 40 | if (m2==m1){ 41 | fout<m1){ 45 | right=y-1; 46 | }else { 47 | left=y+1; 48 | } 49 | } 50 | if (find) break; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /算法例题/[c++基础]结构体的定义和应用/birthday.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | const int MAXN=180; 7 | struct Name{ 8 | string content; 9 | int len; 10 | bool operator <(const Name other) const { 11 | if (len>n; 38 | for(int i=0;i>name>>m>>d; 40 | counts[m][d].add(name); 41 | } 42 | bool has=false; 43 | for(int i=1;i<=12;i++) 44 | for(int j=1;j<=31;j++){ 45 | if (counts[i][j].num>=2) { 46 | has=true; 47 | cout< 2 | using namespace std; 3 | 4 | const int MAXN=65; 5 | int num[MAXN*50+1]; 6 | int n; 7 | int maxv,minv; 8 | int sum; 9 | int ans; 10 | void dfs(int wait,int alreadylen,int needlen,int prelen){ 11 | if (wait==0){//已经拼完所需要的木棍数 12 | cout<=minv;k--){//从前一小段的长度到最小长度枚举 19 | if (num[k]==0||alreadylen+k>needlen) continue; 20 | num[k]--; 21 | dfs(wait,alreadylen+k,needlen,k); 22 | num[k]++; 23 | if (alreadylen==0||alreadylen+k==needlen) break;//拼接一根的第一段和最后一段不需要继续枚举其他值 24 | } 25 | } 26 | } 27 | } 28 | int main(){ 29 | cin>>n; 30 | for(int i=0;i>k; 33 | if (k<=50){ 34 | sum+=k; 35 | num[k]++;//每个长度的段数 36 | minv=min(minv,k); 37 | maxv=max(maxv,k); 38 | } 39 | } 40 | ans=maxv; 41 | while(ans<=sum/2){ 42 | if (sum%ans==0){ 43 | int k=sum / ans; 44 | dfs(k,0,ans,maxv); 45 | } 46 | ans++; 47 | } 48 | cout< 2 | using namespace std; 3 | const int MOD=1000000007; 4 | const int MAXN=500000; 5 | long long a[MAXN+1],b[MAXN+1]; 6 | long long sa[MAXN+1],sb[MAXN+1];//从1向n的累加 7 | long long totalSa[MAXN+1],totalSb[MAXN+1],totalSaSb[MAXN+1];//从n向1的累加 8 | int n; 9 | long long ans; 10 | long long add(long long a,long long b){ 11 | a=a%MOD; 12 | b=b%MOD; 13 | return (a+b)%MOD; 14 | } 15 | long long mul(long long a,long long b){ 16 | a=a%MOD; 17 | b=b%MOD; 18 | return (a*b)%MOD; 19 | } 20 | int main(){ 21 | cin>>n; 22 | for(int i=1;i<=n;i++){ 23 | cin>>a[i]; 24 | sa[i]=(sa[i-1]+a[i]) % MOD; 25 | } 26 | for(int i=1;i<=n;i++){ 27 | cin>>b[i]; 28 | sb[i]=(sb[i-1]+b[i]) % MOD; 29 | } 30 | totalSa[n]=sa[n]; 31 | totalSb[n]=sb[n]; 32 | totalSaSb[n]=mul(sa[n],sb[n]); 33 | for(int i=n-1;i>0;i--){ 34 | totalSa[i]=add(totalSa[i+1],sa[i]); 35 | totalSb[i]=add(totalSb[i+1],sb[i]); 36 | totalSaSb[i]=add(totalSaSb[i+1],mul(sa[i],sb[i])); 37 | } 38 | for(int i=1;i<=n;i++){ 39 | long long t1=mul(sb[i-1],totalSa[i]); 40 | long long t2=mul(sa[i-1],totalSb[i]); 41 | long long t3=mul((n-i+1),mul(sa[i-1],sb[i-1])); 42 | ans=(ans+add(totalSaSb[i],t3)+(MOD-add(t1,t2)))%MOD; 43 | } 44 | cout< 2 | using namespace std; 3 | ifstream fin("none62.in"); 4 | ofstream fout("none62.out"); 5 | const int MAXL=7; 6 | int f[MAXL+1][10]; 7 | int a,b; 8 | 9 | void dp(){ 10 | for(int i=0;i<=9;i++) { 11 | if (i==4) f[0][i]=0; 12 | else f[0][i]=1; 13 | } 14 | for(int i=1;i<=MAXL;i++){ 15 | for(int j=0;j<=9;j++){ 16 | if (j==4) f[i][j]=0; 17 | else 18 | for(int k=0;k<=9;k++){ 19 | if (!(j==6&&k==2)) f[i][j]+=f[i-1][k]; 20 | } 21 | } 22 | 23 | } 24 | } 25 | int calc(int x){ 26 | int t[MAXL+1]={0}; 27 | int k=0; 28 | while(x>0){ 29 | int d=x % 10; 30 | t[k]=d; 31 | k++; 32 | x= x / 10; 33 | } 34 | int tot=0,ans=0; 35 | int i=max(k-1,0); 36 | for(;i>=0;i--){ 37 | int d=t[i]; 38 | for(int j=0;j>a>>b; 51 | while(!(a==0&&b==0)){ 52 | int n1=calc(a-1); 53 | int n2=calc(b); 54 | fout<>a>>b; 56 | } 57 | } -------------------------------------------------------------------------------- /算法例题/[提高训练]动态规划之数位DP/test2.cpp: -------------------------------------------------------------------------------- 1 | //#1020. 「一本通 5.3 练习 1」数字游戏 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("test.in"); 7 | ofstream fout("test.out"); 8 | const int MAXL=10; 9 | const int MAXN=100; 10 | int f[MAXL+1][10][MAXN]; 11 | int a,b,n; 12 | void dp(){ 13 | for(int i=0;i<=9;i++){ 14 | f[0][i][i%n]=1; 15 | } 16 | for(int i=1;i<=MAXL;i++){ 17 | for(int j=0;j<=9;j++){ 18 | for(int k=0;k<=9;k++){ 19 | for(int r=0;r 0) { 29 | int d = x % 10; 30 | t[k] = d; 31 | k++; 32 | x = x / 10; 33 | } 34 | int ans=0,tot=0; 35 | int i = max(k - 1, 0); 36 | for (; i >= 0; i--) { 37 | int d = t[i]; 38 | for(int j=0;j>a>>b>>n){ 49 | memset(f,0,sizeof(f)); 50 | dp(); 51 | int n1=calc(a-1); 52 | int n2=calc(b); 53 | fout< 2 | #include 3 | #include 4 | 5 | #define re register 6 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 7 | #define Rep(i, a, b) for(re int i = (a); i < (b); ++ i) 8 | 9 | const int N = 1e6 + 5; 10 | char s[N]; 11 | int n, ind, fail[N], val[N], c[N][26]; 12 | static inline void ins() { 13 | int len = strlen(s), cur = 0; 14 | Rep(i, 0, len) { 15 | int v = s[i] - 'a'; 16 | if(!c[cur][v]) c[cur][v] = ++ ind; 17 | cur = c[cur][v]; 18 | } val[cur] ++; return ; 19 | } 20 | std::queue q; 21 | static inline void build() { 22 | Rep(i, 0, 26) if(c[0][i]) 23 | fail[c[0][i]] = 0, 24 | q.push(c[0][i]); 25 | while(!q.empty()) { 26 | int u = q.front(); q.pop(); 27 | Rep(i, 0, 26) if(c[u][i]) 28 | fail[c[u][i]] = c[fail[u]][i], 29 | q.push(c[u][i]); 30 | else c[u][i] = c[fail[u]][i]; 31 | } return ; 32 | } 33 | static inline int query() { 34 | int len = strlen(s), cur = 0, ans = 0; 35 | Rep(i, 0, len) { 36 | cur = c[cur][s[i] - 'a']; 37 | for(int t = cur; t && ~val[t]; t = fail[t]) 38 | ans += val[t],val[t] = -1; 39 | } return ans; 40 | } 41 | int main() { 42 | scanf("%d",&n); while(n --) scanf("%s",s), ins(); 43 | build(), scanf("%s",s), printf("%d\n", query()); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /算法模版/GT/spfa.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define re register 5 | #define rep(i, a, b) for(re int i = (a); i <= (b); ++ i) 6 | #define fwd(i, u) for(re int i = head[(u)]; i; i = e[i].nxt) 7 | 8 | const int N = 2e5 + 5; 9 | const int M = 1e6 + 5; 10 | const int INF = 0x3f3f3f3f; 11 | 12 | struct EDGE { int to, w, nxt; } e[M]; 13 | 14 | int n, head[N], dis[N], cnt; bool inq[N]; 15 | 16 | static inline void add(int u, int v, int w) { 17 | e[++ cnt].to = v, e[cnt].nxt = head[u], 18 | e[cnt].w = w, head[u] = cnt; 19 | e[++ cnt].to = u, e[cnt].nxt = head[v], 20 | e[cnt].w = w, head[v] = cnt; return ; 21 | } 22 | 23 | std::queue q; 24 | 25 | static inline void spfa(int s) { 26 | rep(i, 1, n) dis[i] = INF, inq[i] = 0; dis[s] = 0; 27 | q.push(s), inq[s] = 1; while(!q.empty()) { 28 | re int u = q.front(); q.pop(); 29 | inq[u] = 0; fwd(i, u) { 30 | re int v = e[i].to; 31 | if(dis[v] > dis[u] + e[i].w) { 32 | dis[v] = dis[u] + e[i].w; 33 | if(!inq[v]) inq[v] = 1, q.push(v); 34 | } 35 | } 36 | } return ; 37 | } 38 | 39 | int main() { 40 | re int m, s, t, u, v, w; 41 | scanf("%d%d%d%d", &n, &m, &s, &t); 42 | while(m --) 43 | scanf("%d%d%d", &u, &v, &w), 44 | add(u, v, w); 45 | spfa(s); printf("%d\n", dis[t]); 46 | return 0; 47 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]图论之基础树上问题/P1395.cpp: -------------------------------------------------------------------------------- 1 | //P1395 会议 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | const int MAXN=50000; 7 | vector G[MAXN+1]; 8 | int size[MAXN+1];//指定根后,表示以i为根的子树下共有多少个节点 9 | int dp_sum[MAXN+1];//表示以i为根时,整个树中其他节点到i的距离之和 10 | //选定根节点后,第一次树型DP,计算出size[i]和dp_sum[根节点],这里的根节点一般选1 11 | void dfs(int u,int fa){ 12 | size[u]=1; 13 | dp_sum[u]=0; 14 | for(int k=0;k>n; 36 | for(int i=1;i>a>>b; 39 | G[a].push_back(b); 40 | G[b].push_back(a); 41 | } 42 | dfs(1,0); 43 | dfs1(1,0,1); 44 | int ans=INT_MAX; 45 | int node=0; 46 | for(int u=1;u<=n;u++){ 47 | if (ans>dp_sum[u]){ 48 | ans=dp_sum[u]; 49 | node=u; 50 | } 51 | } 52 | cout< 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=9; 6 | const int MAXK=MAXN*MAXN; 7 | const int MAXS=511;//2^9-1 8 | long long dp[MAXN+1][MAXK+1][MAXS+1]; 9 | int n,k; 10 | bool can(int s){ 11 | if (s&(s>>1)) return false; 12 | return true; 13 | } 14 | bool conflict(int s1,int s2){ 15 | if (s1&s2) return true; 16 | else if ((s1>>1)&s2) return true; 17 | else if ((s1<<1)&s2) return true; 18 | else return false; 19 | } 20 | int num[MAXS+1]; 21 | 22 | int lastS; 23 | int main(){ 24 | cin>>n>>k; 25 | lastS=pow(2,n)-1; 26 | for(int s=0;s<=lastS;s++){ 27 | int st=s; 28 | while(st>0){ 29 | num[s]+=st&1; 30 | st=st>>1; 31 | } 32 | } 33 | 34 | dp[0][0][0]=1; 35 | for(int i=1;i<=n;i++){ 36 | for(int j=0;j<=k;j++){ 37 | if (j>n*i) break; 38 | for(int s1=0;s1<=lastS;s1++){ 39 | if (!can(s1)) continue; 40 | for(int s2=0;s2<=lastS;s2++){ 41 | if (!can(s2)) continue; 42 | if (!conflict(s1,s2)&&(j-num[s1]>=0)){ 43 | dp[i][j][s1]+=dp[i-1][j-num[s1]][s2]; 44 | } 45 | } 46 | } 47 | } 48 | } 49 | long long ans=0; 50 | for(int s=0;s<=lastS;s++) ans+=dp[n][k][s]; 51 | cout< 2 | #include 3 | using namespace std; 4 | ifstream fin("getnum.in"); 5 | ofstream fout("getnum.out"); 6 | const int MAXN=10; 7 | int n; 8 | int dp[MAXN*2][MAXN][MAXN]; 9 | int cell[MAXN][MAXN]; 10 | 11 | int main(){ 12 | fin>>n; 13 | int a,b,c; 14 | 15 | fin>>a>>b>>c; 16 | while(a>0&&b>0){ 17 | cell[a-1][b-1]=c; 18 | fin>>a>>b>>c; 19 | } 20 | 21 | for(int d=1;d<2*n-1;d++) 22 | for(int i1=0;i1<=min(d,n-1);i1++) 23 | for(int i2=0;i2<=min(d,n-1);i2++){ 24 | int j1=d-i1; 25 | int j2=d-i2; 26 | if (i1==i2){ 27 | if (i1-1>=0) 28 | dp[d][i1][i1]=dp[d-1][i1-1][i1]+cell[i1][j1]; 29 | }else { 30 | if (i1-1>=0&&i2-1>=0) 31 | dp[d][i1][i2]=max(dp[d-1][i1-1][i2-1]+cell[i1][j1]+cell[i2][j2],dp[d][i1][i2]); 32 | if (i2-1>=0) 33 | dp[d][i1][i2]=max(dp[d-1][i1][i2-1]+cell[i1][j1]+cell[i2][j2],dp[d][i1][i2]); 34 | if (i1-1>=0) 35 | dp[d][i1][i2]=max(dp[d-1][i1-1][i2]+cell[i1][j1]+cell[i2][j2],dp[d][i1][i2]); 36 | dp[d][i1][i2]=max(dp[d-1][i1][i2]+cell[i1][j1]+cell[i2][j2],dp[d][i1][i2]); 37 | } 38 | } 39 | fout< 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | ifstream fin("leaf.in"); 9 | ofstream fout("leaf.out"); 10 | 11 | const int MAXM=10000; 12 | const int INF=0x7fffffff; 13 | int m,n; 14 | int color[MAXM+1]; 15 | vector tree[MAXM+1]; 16 | int dp_min[MAXM+1][2];//dp_min[i][j]表示以i为根的子树中,根结点i着色j时最少的着色点数 17 | bool visited[MAXM+1]; 18 | 19 | void dp(int i){ 20 | visited[i]=true; 21 | if (color[i]>-1) return; 22 | int s=tree[i].size(); 23 | int s0=0,s1=0; 24 | for(int k=0;k>m>>n; 38 | memset(color,-1,sizeof(color)); 39 | for(int i=1;i<=n;i++) { 40 | fin>>color[i]; 41 | dp_min[i][color[i]]=1; 42 | dp_min[i][1-color[i]]=INF; 43 | } 44 | for(int i=0;i>a>>b; 47 | tree[a].push_back(b); 48 | tree[b].push_back(a); 49 | } 50 | memset(visited,false,sizeof(visited)); 51 | dp(n+1); 52 | int ans=min(dp_min[n+1][0],dp_min[n+1][1]); 53 | fout< 2 | #include 3 | #include 4 | #define ll long long 5 | using namespace std; 6 | const int MAXN=1000000000; 7 | const int MAXK=50011; 8 | const int MOD=998244353; 9 | map id; 10 | ll dp[2][MAXK*2]; 11 | ll dp_sum[2]; 12 | int n,m,k; 13 | vector G[MAXK*2]; 14 | 15 | int main(){ 16 | cin>>n>>m>>k; 17 | id[1]=1; 18 | int cnt=1; 19 | for(int i=0;i>a>>b; 22 | if (a!=b){ 23 | //为有限制的点编个新号,在新号上建邻接表 24 | if (id.find(a)==id.end()) id[a]=++cnt; 25 | if (id.find(b)==id.end()) id[b]=++cnt; 26 | G[id[b]].push_back(id[a]); 27 | } 28 | } 29 | //dp[cur][cnt+1]存放本轮中到达没有限制的那些点的方案数总和 30 | dp[0][1]=1; 31 | dp_sum[0]=1; 32 | int cur=1; 33 | for(int j=1;j<=m;j++){ 34 | dp_sum[cur]=0; 35 | for(int i=1;i<=cnt;i++){ 36 | dp[cur][i]=(dp_sum[!cur]+MOD-dp[!cur][i]) % MOD; 37 | for(int k=0;k 2 | #include 3 | using namespace std; 4 | ifstream fin("area.in"); 5 | ofstream fout("area.out"); 6 | 7 | struct Point{ 8 | int x,y; 9 | }; 10 | int dir_off[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 11 | 12 | const int MAXN=100; 13 | int colors[MAXN][MAXN]; 14 | int n,m; 15 | int ans; 16 | 17 | int bfs(int x,int y){ 18 | if (colors[x][y]==0) return 0; 19 | int c=0; 20 | queue qe; 21 | Point start={x,y}; 22 | qe.push(start); 23 | c++; 24 | colors[x][y]=0; 25 | 26 | while(!qe.empty()){ 27 | Point cur=qe.front(); 28 | for(int d=0;d<4;d++){ 29 | int newx=cur.x+dir_off[d][0]; 30 | int newy=cur.y+dir_off[d][1]; 31 | if (newx<0||newx>=n||newy<0||newy>=m) continue; 32 | if (colors[newx][newy]==1){ 33 | Point next={newx,newy}; 34 | qe.push(next); 35 | c++; 36 | colors[newx][newy]=0; 37 | } 38 | } 39 | qe.pop(); 40 | } 41 | return c; 42 | } 43 | int main(){ 44 | fin>>n>>m; 45 | for(int i=0;i>colors[i][j]; 47 | 48 | for(int i=0;ians) ans=area; 53 | } 54 | fout< 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | const int MAXN=100000; 8 | const int INF=0x3fffffff; 9 | 10 | struct Edge{ 11 | int v,w; 12 | }; 13 | vector G[MAXN+1]; 14 | int dist[MAXN+1]; 15 | struct Node{ 16 | int u; 17 | bool operator<(const Node other)const{ 18 | return dist[u]>dist[other.u]; 19 | } 20 | }; 21 | priority_queue pri_qu; 22 | bool in_queue[MAXN+1]; 23 | 24 | int n,m,s; 25 | void dijkstra(int s){ 26 | for(int i=1;i<=n;i++) dist[i]=INF; 27 | dist[s]=0; 28 | pri_qu.push({s}); 29 | in_queue[s]=true; 30 | while(!pri_qu.empty()){ 31 | int u=pri_qu.top().u; 32 | pri_qu.pop(); 33 | in_queue[u]=false; 34 | for(int k=0;k 2 | 3 | typedef long long ll; 4 | 5 | #define re register 6 | const ll N = 2e5 + 5; 7 | const ll SGT = N << 5; 8 | const ll mod = 19831205ll; 9 | 10 | ll rt, ind; 11 | ll ls[SGT], rs[SGT]; 12 | ll sum[SGT], tag[SGT]; 13 | 14 | static inline void pd(ll p, ll l, ll r) { 15 | if(!tag[p]) return; re ll mid = (l + r) >> 1; 16 | if(!ls[p]) ls[p] = ++ ind; sum[ls[p]] = tag[p] * (mid - l + 1); 17 | if(!rs[p]) rs[p] = ++ ind; sum[rs[p]] = tag[p] * (r - mid); 18 | tag[ls[p]] = tag[rs[p]] = tag[p]; tag[p] = 0; return; 19 | } 20 | 21 | void modify(ll &p, ll l, ll r, ll L, ll R, ll x) { 22 | if(l > R || r < L) return; if(!p) p = ++ ind; 23 | if(L <= l && r <= R) { tag[p] = x; sum[p] = x * (r - l + 1); return; } 24 | pd(p, l, r); re ll mid = (l + r) >> 1; 25 | modify(ls[p], l, mid, L, R, x), modify(rs[p], mid + 1, r, L, R, x); 26 | sum[p] = (sum[ls[p]] + sum[rs[p]]) % mod; return; 27 | } 28 | 29 | ll query(ll p,ll l,ll r,ll L,ll R) { 30 | if(!p || l > R || r < L) return 0; 31 | if(l >= L && r <= R) return sum[p]; 32 | pd(p, l, r); re ll mid = (l + r) >> 1; 33 | return (query(ls[p], l, mid, L, R) + query(rs[p], mid + 1, r, L, R)) % mod; 34 | } 35 | 36 | ll n, m; 37 | 38 | int main() { 39 | scanf("%lld%lld", &n, &m); 40 | re ll opt, l, r, x; while(m --) { 41 | scanf("%lld%lld%lld", &opt, &l, &r); 42 | if(opt < 2) scanf("%lld", &x), modify(rt, 1, n, l, r, x); 43 | else printf("%lld\n", query(rt, 1, n, l, r)); 44 | } return 0; 45 | } -------------------------------------------------------------------------------- /算法例题/[洛谷题单]二叉堆与ST表/P1801.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int MAXN=200000; 5 | int a[MAXN+10],u[MAXN+10]; 6 | int n,m; 7 | priority_queue maxheap; 8 | priority_queue,greater > minheap; 9 | 10 | int main(){ 11 | cin>>m>>n; 12 | for(int i=0;i>a[i]; 13 | for(int i=0;i>u[i]; 14 | 15 | int maxheap_cursize=0; 16 | int maxheap_limitsize=0; 17 | int uindex=0; 18 | for(int i=0;i=minheap.top()) minheap.push(a[i]); 23 | else { 24 | if (maxheap_cursize 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXT=100; 6 | const int MAXINT=1000000000; 7 | struct Edge{ 8 | int v,w; 9 | }; 10 | vector G[MAXT+10]; 11 | int dist[2][MAXT+10]; 12 | map id; 13 | int N,T,S,E; 14 | int main(){ 15 | cin>>N>>T>>S>>E; 16 | int cnt=1; 17 | id[S]=cnt++; 18 | id[E]=cnt++; 19 | 20 | for(int i=0;i>w>>u>>v; 23 | if (id.find(u)==id.end()) id[u]=cnt++; 24 | if (id.find(v)==id.end()) id[v]=cnt++; 25 | G[id[u]].push_back({id[v],w}); 26 | G[id[v]].push_back({id[u],w}); 27 | } 28 | for(int i=1;i<=cnt;i++){ 29 | dist[0][i]=MAXINT; 30 | dist[1][i]=MAXINT; 31 | } 32 | int u=id[S]; 33 | for(int k=0;k 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=20; 6 | const int MAXS=MAXN*100; 7 | int a[MAXN+1]; 8 | int n,m; 9 | bool removed[MAXN+1]; 10 | bool can[MAXS+1]; 11 | int maxtotal; 12 | void calc(){ 13 | memset(can,false,sizeof(can)); 14 | can[0]=true; 15 | int sum=0; 16 | int total=0; 17 | for(int i=1;i<=n;i++){ 18 | if (!removed[i]){ 19 | sum+=a[i]; 20 | for(int j=sum;j>=a[i];j--) //此循环要从大到小枚举,否则a[i]就会被多次使用。这是一个背包问题 21 | if (!can[j]&&can[j-a[i]]){ 22 | can[j]=true; 23 | total++; 24 | } 25 | } 26 | /*上面这部分也可以这样写 27 | if (!removed[i]){ 28 | for(int j=sum;j>=0;j--) 29 | if (can[j]&&!can[j+a[i]]){ 30 | can[j+a[i]]=true; 31 | total++; 32 | } 33 | sum+=a[i]; 34 | }*/ 35 | } 36 | maxtotal=max(maxtotal,total); 37 | } 38 | void dfs(int start,int num){ 39 | if (num==0){ 40 | calc(); 41 | }else { 42 | for(int i=start;i<=n-(num-1);i++){ 43 | removed[i]=true; 44 | dfs(i+1,num-1); 45 | removed[i]=false; 46 | } 47 | } 48 | } 49 | int main(){ 50 | cin>>n>>m; 51 | for(int i=1;i<=n;i++) { 52 | cin>>a[i]; 53 | } 54 | dfs(1,m); 55 | cout< 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("cowfood.in"); 7 | ofstream fout("cowfood.out"); 8 | const int MAXN = 12; 9 | const int MAXS = 4096; 10 | int m, n; 11 | int flag[MAXN + 1]; 12 | long long dp[MAXN + 1][MAXS + 1];//dp[i][s]表示前i行中,第i行的状态为s时的方案数 13 | vector states; 14 | long long ans; 15 | 16 | int main() { 17 | fin >> m >> n; 18 | for (int i = 1; i <= m; i++) { 19 | for (int j = 0; j < n; j++) { 20 | int a; 21 | fin >> a; 22 | flag[i] = (flag[i] << 1) + a; 23 | } 24 | } 25 | 26 | for (int s = 0; s <= (2 << n) - 1; s++) { 27 | if (s&(s<<1)) continue; 28 | states.push_back(s); 29 | } 30 | int count = states.size(); 31 | //dp 32 | dp[0][0] = 1; 33 | for (int i = 1; i <= m; i++) { 34 | for (int i1 = 0; i1 < count; i1++) { 35 | int s1 = states[i1]; 36 | if (((~flag[i]) & s1) > 0) 37 | continue; 38 | for (int i2 = 0; i2 < count; i2++) { 39 | int s2 = states[i2]; 40 | if ((s1 & s2) > 0) continue; 41 | dp[i][s1] = (dp[i][s1]+dp[i - 1][s2]) % 100000000; 42 | } 43 | } 44 | } 45 | //output 46 | 47 | for (int i = 0; i < count; i++) { 48 | int s = states[i]; 49 | ans =(ans+ dp[m][s]) % 100000000; 50 | } 51 | fout << ans; 52 | } --------------------------------------------------------------------------------