数据结构
文章平均质量分 54
f_zyj
一个追逐蝴蝶的人!
展开
-
逆序数
ACM模版归并排序求逆序数/* * 也可以用树状数组做 * a[0...n-1] cnt=0; call: MergeSort(0, n) */const int N = 1010;int a[N];int c[N];int cnt = 0;void MergeSort(int l, int r){ int mid, i, j, tmp; if (r > l +原创 2016-07-22 14:52:12 · 5659 阅读 · 0 评论 -
并查集
ACM模版带权值的并查集/* * INIT: makeset(n); * CALL: findset(x); unin(x, y); */const int N = 1010;struct lset{ int p[N], rank[N], sz; void link(int x, int y) { if (x == y) {原创 2016-07-22 15:02:57 · 1897 阅读 · 6 评论 -
快排
ACM模版快排void ksort(int l, int h, int a[]){ if (h < l + 2) { return ; } int e = h, p = l; while (l < h) { while (++l < e && a[l] <= a[p]); while (--h > p原创 2016-07-22 15:10:55 · 1470 阅读 · 0 评论 -
最长公共递增子序列
ACM模版最长公共递增子序列/* * 最长公共递增子序列 O(n^2) * f记录路径,DP记录长度, 用a对b扫描,逐步最优化。 */const int N = 1010;int f[N][N], dp[N];int gcis(int a[], int la, int b[], int lb, int ans[]){ // a[1...la], b[1...lb] in原创 2016-07-22 17:10:21 · 1241 阅读 · 0 评论 -
最长公共子序列
ACM模版最长公共子序列const int N = 1010;int a[N][N];int LCS(const char *s1, const char *s2){ // s1:0...m, s2:0...n int m = (int)strlen(s1), n = (int)strlen(s2); int i, j; a[0][0] = 0; for (i原创 2016-07-22 18:33:24 · 1342 阅读 · 0 评论 -
最少找硬币问题
ACM模版最少找硬币问题/* * 贪心策略-深度搜索 */int value[7] = {100, 50, 20, 10, 5, 2, 1};int count[7]; // count[i]:value[i]硬币的个数int res[7];bool flag;void DFS(int total, int p);int main(){ int pay = 0;原创 2016-07-22 21:04:07 · 1696 阅读 · 0 评论 -
棋盘分割
ACM模版棋盘分割/* * 棋盘分割 * 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部 * 分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最 * 后剩下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着棋盘格子的边 * 进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分 * 值之和。现在需要把棋盘按上述规则分割成原创 2016-07-22 23:38:28 · 1391 阅读 · 0 评论 -
区间最大频率
ACM模版区间最大频率参考题目链接: POJ 3368 Frequent values/* * 求区间中数出现的最大频率 * 方法一:线段树. * 先离散化。因为序列是升序,所以先将所有值相同的点缩成一点。这样n规模就缩小了。建立一个数据结构 * 记录缩点的属性:在原序列中的值id,和该值有多少个num比如序列 * 10 * -1 -1 1 1 1 1 3 10 10 10原创 2016-07-23 01:40:35 · 1428 阅读 · 0 评论 -
堆栈
ACM模版堆栈const int MAXSIZE = 10000;int a[MAXSIZE], heapsize;inline void swap(int i, int j){ int temp = a[i]; a[i] = a[j]; a[j] = temp; return ;}inline int Parent(int i){ return i原创 2016-07-23 01:50:30 · 941 阅读 · 0 评论 -
莫队算法
ACM模版莫队算法可以解决一类静态,离线区间查询问题。参考题目链接: BZOJ 2038 [2009国家集训队]小Z的袜子(hose) 题解: 只需要统计区间内各个数出现次数的平方和。莫队算法,两种方法,一种是直接分成sqrt(n)块,分块排序。 另外一种是求得曼哈顿距离最小生成树,根据manhattan MST的dfs序求解。分块const int MAXN = 50010;cons原创 2016-07-24 23:08:18 · 2465 阅读 · 0 评论 -
NYOJ-201-作业题
ACM模版描述小白同学这学期有一门课程叫做《数值计算方法》,这是一门有效使用数字计算机求数学问题近似解的方法与过程,以及由相关理论构成的学科……今天他们的Teacher S,给他们出了一道作业题。Teacher S给了他们很多的点,让他们利用拉格朗日插值公式,计算出某严格单调函数的曲线。现在小白抄下了这些点,但是问题出现了,由于我们的小白同学上课时走了一下神,他多抄下来很多点,也就是说这些点整体连线原创 2016-07-26 00:48:03 · 464 阅读 · 0 评论 -
51Nod-1137-矩阵乘法
ACM模版描述给出2个N * N的矩阵M1和M2,输出2个矩阵相乘后的结果。Input 第1行:1个数N,表示矩阵的大小(2 <= N <= 100) 第2 - N + 1行,每行N个数,对应M1的1行(0 <= M1[i] <= 1000) 第N + 2 - 2N + 1行,每行N个数,对应M2的1行(0 <= M2[i] <= 1000)Output 输出共N行,每行N个数,对应M1 *原创 2016-07-26 14:24:34 · 418 阅读 · 0 评论 -
RMQ
ACM模版一维/* * 求最大值,数组下标从1开始。 * 求最小值,或者最大最小值下标,或者数组从0开始对应修改即可。 */const int MAXN = 50010;int dp[MAXN][20];int mm[MAXN];// 初始化RMQ,b数组下标从1开始,从0开始简单修改void initRMQ(int n, int b[]){ mm[0] = -1;原创 2016-07-20 17:03:24 · 1332 阅读 · 2 评论 -
51Nod-1174-区间中最大数
ACM模版描述给出一个有N个数的序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,最大的数是多少。 例如: 1 7 6 3 1。i = 1, j = 3,对应的数为7 6 3,最大的数为7。(该问题也被称为RMQ问题)Input 第1行:1个数N,表示序列的长度。(2 <= N <= 10000) 第2 - N + 1行:每行1个数,对应序列中的元素。(0 <= S[i]原创 2016-07-26 14:54:42 · 751 阅读 · 0 评论 -
2016码农谷全国大学生程序设计邀请赛(第一轮资格赛)
ACM模版额,这次有些尴尬了,题虽然不难,但是睡过了四十五分钟,着实有些慌张,然后,做题就粗心了,少看了条件,最为尴尬的是,只能提交一次……试题一 对码农的编程水平进行排名描述老码农要对N个码农的编程水平进行排序,这些码农的编号依次为1,2,3,…,N,但老码农无法获得他们的具体水平数据,只知道相对水平,例如,“P Q”表示P的水平比Q高。请编写程序,帮助老码农进行排序。 说明:符合条件的排序可能原创 2016-07-16 18:08:01 · 1135 阅读 · 2 评论 -
二叉排序树
ACM模版二叉排序树typedef bool Status;// 二叉树的二叉链表结点结构定义typedef struct BiTNode{ int data; struct BiTNode *lchild, *rchild;} BiTNode, *BiTree;// 递归查找二叉排序树T中是否存在Key// 指针f指向T的双亲,其初始值调用值为NULL// 若查找原创 2016-07-28 04:21:20 · 487 阅读 · 0 评论 -
51Nod-1001-数组中和等于K的数对
ACM模版描述题解这道题两种办法解,两种办法的通性是都需要排序,但是数据结构截然不同。 第一种办法是源数据进行从小到大排序,然后定一个哨兵flag,来卡住查找的范围,以此来达到减少查找次数。 第二种办法比较巧,将复杂度为O(n*m)降低为O(n)。效率略微提高,使用的手段是将数据结构改造了一下,给源数据捆绑了一个antival的辅助数据。当a[i].val < k / 2时,a[i].antiv原创 2016-07-30 03:51:40 · 733 阅读 · 0 评论 -
51Nod-1009-数字1的数量
ACM模版描述题解一道动态规划题,考点是数位dp,这里提供两种异曲同工之妙的解法。虽然都是数位dp,但是思路有略微差异。代码One:#include <iostream>#include <cmath>#include <cstring>//#pragma warning(disable:4996)using namespace std;typedef long long ll;ll s;ll原创 2016-07-30 14:36:41 · 1854 阅读 · 0 评论 -
51Nod-1090-3个数和为0
ACM模版描述题解数据比较水,复杂度为O(n^3)一样可以过。但是想要优化起来比较麻烦,细节问题挺多的。代码#include <iostream>#include <algorithm>using namespace std;const int MAXN = 1010;int A[MAXN];int main(int argc, const char * argv[]){// freop原创 2016-07-30 23:37:48 · 926 阅读 · 0 评论 -
51Nod-1091-线段的重叠
ACM模版描述题解先进行排序,然后互相比较,留最长。然而单纯地互相比较会在最后几组数据超时,所以需要进行一个小小的优化,L[j].y > L[i].y时,直接跳出i与后续的j的比较。如此,AC之……代码#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int MAXN = 5e4 +原创 2016-07-31 00:55:42 · 457 阅读 · 0 评论 -
51Nod-1344-走格子
ACM模版描述题解逐个处理,当energy小于0时,res就加上-energy,最后直接出结果。一道水题。代码#include <iostream>#include <cstdio>using namespace std;int main(int argc, const char * argv[]){ //freopen("input.txt", "r", stdin); int原创 2016-07-31 02:02:18 · 1381 阅读 · 0 评论 -
51Nod-1010-只包含2 3 5的数
ACM模版描述题解先打表生成丑数,然后二分查找到大于等于n的第一个数。代码#include <iostream>#include <cstdio>#include <queue>using namespace std;typedef unsigned long long ull;const int MAXN = 1e4 + 1e3;/* * Ugly Numbers * Ugly numbe原创 2016-07-31 10:06:05 · 607 阅读 · 0 评论 -
51Nod-1278-相离的圆
ACM模版描述题解将圆的问题转化为线段问题,按线段左端排序后,二分查找即可。 还有一种比较巧妙的办法是,将所有的线段的起点和终点存入一个数组中,然后排序,初始化num=圆的个数(线段条数),sum=0,然后从头开始遍历,遇见起点则num–,遇到终点则sum+=num。代码#include <iostream>#include <cstdio>#include <algorithm>using原创 2016-08-03 21:43:59 · 804 阅读 · 0 评论 -
51Nod-1042-数字0~9的数量
ACM模版描述题解数位dp,和51Nod 1009 数字1的数量是同类型题,方法一致。但是需要考虑的情况多了些,所以需要注意的细节也随之多了许多,一不小心,我就碰见了BUG,这个BUG,说起来好心酸,从七月找到了八月……问题在于这道题需要考虑到0的个数,而0的个数和其他的不一样,因为数字前缀必须是非0的,也就是说需要把所有0...、00...、000...等情况系数筛除。代码#include <io原创 2016-08-01 04:39:41 · 1200 阅读 · 0 评论 -
Trie树
ACM模版k叉/* * INIT: init(); * 注: tree[i][tk]>0时表示单词存在, 当然也可赋予它更多含义; */const int tk = 26, tb = 'a'; // tk叉; 起始字母为tb;const int N = 1010; // N: 最大结点个数int top, tree[N][tk + 1];void i原创 2016-07-22 01:25:59 · 1383 阅读 · 0 评论 -
线段树
ACM模版求矩形并的面积(线段树+离散化+扫描线)参考题目链接: POJ 1151 Atlantis Each test case starts with a line containing a single integer n (1 <= n <= 100) of available maps. The n following lines describe one map each. Ea原创 2016-07-21 21:54:56 · 2694 阅读 · 0 评论 -
左偏树
ACM模版左偏树/* * 合并复杂度 O(log N) * INIT: init()读入数据并进行初始化; * CALL: merge() 合并两棵左偏树; * ins() 插入一个新节点; * top() 取得最小结点; * pop() 取得并删除最小结点; * del() 删除某结点; * add原创 2016-07-21 16:58:37 · 1348 阅读 · 2 评论 -
Treap
ACM模版Treaplong long gcd(long long a, long long b){ if (b == 0) { return a; } else { return gcd(b, a % b); }}const int MAXN = 300010;int num[MAXN], st[MAXN];st原创 2016-07-21 04:35:08 · 1042 阅读 · 0 评论 -
动态树
ACM模版动态树参考题目链接: HDU 4010 Query on The Trees/* * 切割、合并子树,路径上所有点的点权增加一个值,查询路径上点权的最大值 * 动态维护一组森林,要求支持一下操作: * link(a,b): 如果a,b不在同一颗子树中,则通过在a,b之间连边的方式,连接这两颗子树 * cut(a,b): 如果a,b在同一颗子树中,且a!=b,则将a视为这原创 2016-07-21 00:37:25 · 1237 阅读 · 0 评论 -
伸展树
ACM模版伸展数/* * 伸展树(Splay Tree) * 题目:维修数列。 * 经典题,插入、删除、修改、翻转、求和、求和最大的子序列 */#define Key_value ch[ch[root][1]][0]const int MAXN = 500010;const int INF = 0x3f3f3f3f;int pre[MAXN], ch[MAXN][2], key原创 2016-07-20 22:22:37 · 1311 阅读 · 0 评论 -
树链剖分
ACM模版点权参考题目链接: HDU 3966 Aragorn’s Story/* * 基于点权,查询单点值,修改路径的上的点权 */const int MAXN = 50010;struct Edge{ int to, next;} edge[MAXN * 2];int head[MAXN], tot;int top[MAXN]; // top[v]表示v所在的重链原创 2016-07-20 18:41:48 · 1177 阅读 · 0 评论 -
划分树
ACM模版划分树/* * 划分树(查询区间第k大) */const int MAXN = 100010;int tree[20][MAXN]; // 表示每层每个位置的值int sorted[MAXN]; // 已经排序好的数int toleft[20][MAXN]; // toleft[p][i]表示第i层从1到i有数分入左边void build(int原创 2016-07-20 16:30:47 · 1583 阅读 · 0 评论 -
51Nod-1070-Bash游戏 V4
ACM模版描述题解这道题存在一些问题,对于1没有进行合法的规定,如果加上一句当石子数为1时,B赢,那么就完美了。因为经过找规律发现,只要石子数为斐波那契数列中的一项,B赢,反之,A赢,所以很简单喽……这里要注意的是打表的数目,因为我一开始打表时FB[]数组定义的有些大,结果超出了数据范围,只有前47个数没有出错,后续的全部为负数(因为数据溢出了),然后我一二分查找,结果输出的全部为A……尴尬死了。代原创 2016-08-02 09:57:18 · 444 阅读 · 0 评论 -
51Nod-1043-幸运号码
ACM模版描述题解动态规划,dp[i][j]表示i个数和为j的总数(这里包括开头为0的情况),则: dp[i][j] = dp[i - 1][j - k](k:0 to 9) 最后,我们只需要用去掉0打头的情况*没有去掉0打头的情况累加并取模即可。 ans = (ans + dp[n & 1][i] * (dp[n & 1][i] - dp[(n - 1) & 1][i])) % m原创 2016-08-05 23:57:17 · 1112 阅读 · 0 评论 -
51Nod-1094-和为k的连续区间
ACM模版描述题解求前N项和存储起来,然后前后相减与K对比,水题……代码#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int MAXN = 1e4 + 10;int A[MAXN];int sum[MAXN];int main(int argc, const char * argv原创 2016-08-02 21:00:32 · 1080 阅读 · 0 评论 -
HDU-5791-Two
ACM模版描述题解类似于最长公共子序列问题,略微不同,另外需要考虑到重复状态的去重与否。代码#include <iostream>#include <cstdio>typedef long long ll;using namespace std;const int mod = 1000000007;int a[1005], b[1005];long long dp[1005][1005];int原创 2016-08-02 22:25:27 · 626 阅读 · 0 评论 -
机器工作调度
ACM模版机器工作调度2台机器,n件任务,必须先在S1上做,再在S2上做. 任务之间先做后做任意.求最早的完工时间. 这是一个经典问题: 2台机器的情况下有多项式算法(Johnson算法),3台或以上的机器是NP-hard的.Johnson算法: (1)把作业按工序加工时间分成两个子集,第一个集合中在S1上做的时间比在S2上少,其它的作业放到第二个集合; 先完成第一个集合里面的作业,再完原创 2016-07-22 15:30:45 · 1806 阅读 · 0 评论 -
51Nod-1205-流水线调度
ACM模版描述题解机器调度问题,这是一个经典问题: 2台机器的情况下有多项式算法(Johnson算法),3台或以上的机器是NP-hard算法。代码#include <iostream>#include <algorithm>#include <cstdio>using namespace std;const int MAXN = 5e4 + 5;struct task{ int a;原创 2016-08-27 17:54:02 · 1201 阅读 · 0 评论 -
51Nod-1243-排船的问题
ACM模版描述题解万万没想到,这道题用的是二分……对绳子长度进行二分,然后逐个对比,看能否排放下所有船只,绳子长度在0~M-1之间,所以……顺理成章的二分,只是查找的不是v,而是长度为mid的绳子能否拴住所有的船,这里我们用int judge(int d)函数来判断,如果能拴住,则说明最长绳子的长度最短小于等于d,否则大于等于d,可AC……代码#include <iostream>#include原创 2016-08-28 18:27:19 · 884 阅读 · 4 评论 -
51Nod-1097-拼成最小的数
ACM模版描述题解排序,然后按照输出规定输出即可。 这里的重点是排序准则: 如果两个数长度一样,则从小到大排;如果两个数长度不一样,则从高位开始比较,依然遵循从小到大排(比如说1、12,11、12,11、112、1122)。重要的事说一遍,细节决定成败! 要尽量考虑完全各种情况,尤其是当A是B前缀时的情况!!!如:4177、41774,4577、45774,194、194180,……代码#in原创 2016-08-06 18:41:12 · 704 阅读 · 0 评论