
算法
文章平均质量分 68
qichi_bj
这个作者很懒,什么都没留下…
展开
-
动态区间最小值查询,支持点设置,线段树
从周二来镇江出差到现在已经3天了。这几天镇江细雨绵绵,天气异常阴冷,更兼近来事情多有不顺,心情比较沮丧。今天与客户讨论结束,下午闲暇,却心乱如麻,半天时间在焦躁中浪费了。晚上静下来,整理了一下前一阵看的线段树算法:// 用线段树实现动态区间最小值查询,对源数组A[0..N-1]支持更新操作和查询操作:// update(int i, int v) 将数组第i个元素值设置为v, i属于区间原创 2012-11-22 23:28:34 · 684 阅读 · 0 评论 -
动态连续区间和查询,Binary Index Tree 算法
给定N元数组A[0]...A[N-1],设计一个数据结构,支持两种操作:1. add(i,v) 将A[i]元素值增加v,下标i区间为[0..N-1]2. sum(L,R) 查询连续区间和 A[L] + A[L+1] + ... + A[R], 下标L,R区间为[0..N-1]二叉索引树 Binary Index Tree 支持动态连续区间和的查询,BIT含有N个结点,每个结点存原创 2012-11-18 15:44:11 · 2553 阅读 · 0 评论 -
Aho-Corasick automation,AC 自动机
构造 AC 自动机分两步:第一步构造 Trie 树比较简单;第二步给 Trie 树的每个结点加 fail 边。给一个结点添加 fail 边时,从其父结点开始沿 fail 边开始搜索,直到找到一个匹配结点(即 p.next[c] != null 的结点,c 为当前字符),或者找到根结点,fail 边即指向找到的匹配结点或根结点,递推时按照 Trie 树的层次遍历,保证访问到某结点时其父结点的 fai原创 2012-12-04 14:52:05 · 794 阅读 · 0 评论 -
火柴拼接数字的游戏
用 n 根火柴棍能组成多少个非负整数?火柴不必用完,如2根火柴可以组成 1 ,3 根火柴可以组成 1 7 ,4 根火柴可以组成 1, 4, 7, 11数字 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 需要的火柴数 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 令 d[i] 为用 i 根火柴(全部用上)可以组成的原创 2012-12-09 17:43:49 · 1952 阅读 · 1 评论 -
带标号的连通图计数
统计 n 个顶点的连通图有多少个,每个顶点有标号。记 f(n) 为带标记的连通图的个数,g(n) 为带标记的非连通图的个数,则 f(n) + g(n) = h(n) = 2^(n(n-1)/2) ;考虑 g(n) 的计数:按照结点 1 所在的联通分量的点数分类,设结点 1 所在联通分量包含 k 点(k = 1 ... n-1)则有 C(n-1, k -1) 种不同情况,每种情况下,结点 1 所在原创 2012-12-10 21:09:13 · 2352 阅读 · 0 评论 -
多叉树计数,Exploring Pyramids, NEERC 2005, LA 3516
给一颗多叉树,每个结点的子结点都有从左到右的顺序,从根结点开始,每次尽量选择靠左的分支走,走不通就回溯,把遇到的字母记录下来,可以得到一个序列。 给定一个序列,问有多少树和他对应?令 S 表示给定序列,d[i][j] 表示字符区间 [i,j] 对应的不同的树的数目,则有如下边界条件:如果 i == j 则 d[i][j] = 1 如果 S[i] != S[j] 则 d[i][j]原创 2012-12-11 22:17:41 · 943 阅读 · 0 评论 -
村民排队问题
在一个村庄里有 N ( 1有父子关系的村民可以组成一颗树,所有这些树加上一个虚拟根结点组成一颗树,其结点数目为 N+1;定义 f(r) 为以 r 为根结点的树对应的排列数目,s(r) 为以 r 为根结点的树的结点个数;对 r 树来说,在 s(r) 个位置中第一个位置分配给 r ,其他 s(r)-1 个位置分配给其子树中的结点;假设 r 结点有 n 个子树为 c1, c2, ... , ck原创 2012-12-12 17:15:21 · 686 阅读 · 0 评论 -
UVa11361 Investigating Div-Sum Property
给定整数 A ,B ,K 求 区间[A, B] 中被 K 整除且各位数之和被 K 整除的数有多少个,1 <= A <= B < 2^31 且 0< K < 10000package UVa11361;import java.util.Scanner;public class Main { private static final int MAX_BIT = 16; pr原创 2012-12-29 11:53:04 · 569 阅读 · 0 评论 -
UVa10883 Supermean
这道题开始没有注意越界问题,当 n = 5000 是取组合数非常大,而 2^n 也非常大,需要用自然对数处理一下才能处理 C(N,K)*A[k]/2^N 的求值,而且取对数的时候要分正负零各种情形考虑,提交了很多次,终于 AC 了。package UVa10883;import java.util.Scanner;public class Main { public static原创 2012-12-30 12:10:44 · 1004 阅读 · 0 评论 -
全域哈希和完全哈希
键集合 U 包含 n 个键,哈希表 T 包含 m 个槽,集合 H 包含一些哈希函数。如果 H 满足:对于任意 x, y ∈ U, 集合 { h | h∈H && h(x) = h(y) } 的元素个数等于 |H|/m,则称 H 为全域哈希;对全域哈希 H,从 H 中随机选择哈希函数,任意键 x, y 冲突概率等于 1/m;对于全域哈希 H,从中随机选择 h 作为哈希函数,对任意的键 x,与他冲突原创 2013-01-05 22:15:59 · 5348 阅读 · 1 评论 -
最小费用最大流算法
反复寻找费用最小路径,然后在该路径上使流量增大;寻找最小费用路径时,不考虑剩余容量为 0 的边;虽然网络流图是有向图,但是为了寻找包含反向边的路径,对每条正向边都有可能生成出反向边(当正向边上有流量时,就有容量等于流量的反向边);NetworkFlowGraph.h 类头文件:/* * NetworkFlowGraph.h * * Created on: 2013-1-22原创 2013-01-23 14:02:32 · 2954 阅读 · 0 评论 -
UVa 10139 Factovisors
这道题同样的代码用 JAVA 会超时,用 C++ 才通过。#include #include #include using namespace std;// 素数筛的数组长度long LEN = 1 << 16;// 用于保存筛出的素数vector primes;// 利用筛法求 2^16 以内的素数,保存到 primes 全局变量void init() { bo原创 2013-01-13 08:16:26 · 514 阅读 · 0 评论 -
无向图的割切点
求无向图的割切点,删除割切点及其相关的边将导致图的连通分量增加,采用了邻接矩阵表示图。//============================================================================// Name : CutPointProblem.cpp// Author : Qichi// Version :原创 2013-01-18 09:58:47 · 523 阅读 · 0 评论 -
动态区间最大值最小值区间和查询,支持区间设置,线段树
对区间 [0,N-1] 支持两种操作:1. update(L, R, v) 将区间[L,R] 的所有值设置为 v;2. query(L, R) 查询区间 [L, R] 的最大值、最小值、区间和;利用线段树解决该问题,更新时,对某区间的设置操作不需要分解到其每一个子区间(否则可能要更新每一个叶子节点),只需在该区间上做设置标记;在查询时,遇到有标记的区间,将标记 pushdown 到子区原创 2012-12-03 09:21:57 · 5494 阅读 · 0 评论 -
最大子矩阵,City Game,SEERC 2004,LA3029
给定一个MN的矩阵,其中一些格子是空地(F),其他是障碍(R),找出一个全部由F组成的面积最大的子矩阵。JAVA代码给出O(N^2)算法。参考文献:《算法竞赛入门经典训练指南》P51,刘汝佳,陈锋package ProgrammingContest;public class CityGame_SEERC_2004 { public static int min(int x原创 2012-11-17 21:13:20 · 863 阅读 · 0 评论 -
字符串组合问题
给两个串A[1..m]和B[1..n],现在要把B插入到A中,也就是说,得到一个A[1..p]B[1..n]A[p+1..m]的形式,也可以把B放到A的最前面或最后面。问能得到的字典序最小的串。B插入A总共有m+1中方式,每种方式对应于一个[0..m]间的数字(0表示插入在最前面,i表示插入在A[i]之后)。定义F(i,j) 为A[i..m]与B[j..n]的组合中字典序最小的串对应的原创 2012-10-28 20:12:29 · 386 阅读 · 0 评论 -
Remember the word, LA 3942, Trie Tree
给出一个由S个不同单词组成的字典和一个长字符串,把这个字符串分解成若干个单词的连接(单词可以重复使用),有多少种方法?比如4个单词 a、b、cd、ab 则 abcd 有两中分解方法:a+b+cd 和 ab + cd。参考文献:《算法竞赛入门经典训练指南》P208,刘汝佳,陈锋public class Trie { private final static int MAX_SIZE原创 2012-11-25 17:04:25 · 463 阅读 · 0 评论 -
动态平衡二叉搜索树的简易实现,Treap 树
Treap 树是一种易于实现的近似平衡的二叉搜索树。Treap 每个结点包括值和优先级两个属性,值满足二叉搜索树性质(左public class TreapTree { public static class Node { public int v; public int p; Node lc; Node rc; public Node(int x)原创 2012-11-27 21:59:49 · 878 阅读 · 0 评论 -
多路文件归并,败者树算法
闲来无事,做了一个多路文件归并的工具,用败者树选择从多路输入中选择一个最小者,空间复杂度为O(K),K为归并输入的路数。该实现没有考虑最佳归并路径,等日后有空了再实现一个最佳归并路径的算法;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;impor原创 2012-11-22 20:55:27 · 636 阅读 · 0 评论 -
后缀数组,Manber & Mayer 倍增算法
后缀数组是解字符串问题的一个工具,后缀数组的构建复杂度为O(NLogN),在后缀数组的基础上进行模板匹配的复杂度为O(MLogN)。下面的JAVA代码适用于只包含0-255之间字符的字符串的后缀数组的构建。参考文献:《算法竞赛入门经典训练指南》P221,刘汝佳,陈锋package ProgrammingContest;public class ArrayOfSuffix {原创 2012-11-17 20:57:56 · 1063 阅读 · 0 评论 -
后缀数组的最长公共前缀
除了后缀数组SA之外,对于字符串处理的问题,通常还需要RANK和HEIGHT两个数组。RANK数组存储每个后缀的排名,RANK[i]∈[0..n-1]为后缀i的排名。HEIGHT存储排名相邻的两个后缀的最长公共前缀,HEIGHT[i]=LCP(SA[i-1], SA[i]),即排名i-1和i的两个后缀的最长公共前缀的长度。在HEIGHT的基础上,如果要计算LCP[i,j],可以运用以下性质:L原创 2012-11-18 10:39:03 · 2639 阅读 · 0 评论 -
质因数分解算法
看《单墫老师教你学数学》了解了一个很巧妙的质因数分解的算法,C++代码如下:/* * 求正整数n的最小质因数 */uint64_t FactorDecomposer::minimalPrimeFactor(uint64_t n) { if ( n % 2 == 0 ) return 2; uint64_t M = n, N = n, b = 3, r = 0; while原创 2012-10-20 15:03:42 · 1123 阅读 · 0 评论 -
X-Plosives问题, LA 3644, 并查集算法
利用并查集检测回路。package ProgrammingContest;import java.io.File;import java.util.Scanner;public class XPlosives_LA_3644 { public int MAX = 100000; public int[] P = new int[MAX]; //初始化并查集,每个元素为一个原创 2012-11-15 22:14:12 · 553 阅读 · 0 评论 -
基于数组的基数排序
实现了一个基于数组的基数排序工具类,备用。public class ArrayBasedRadixSort { //M是基数, 数字的每一位为0..M-1 private int M = 0; //EXP[i]=M^i; private int[] EXP = null; //初始化 public ArrayBasedRadixSort(int M) { this.M = M原创 2012-11-15 22:01:15 · 1004 阅读 · 1 评论 -
区间最小值查询,RMQ,Sparse-Table算法
给一个N元数组A[0..N-1],设计一个数据结构,支持查询操作Query(L,R),计算min{A[L]...A[R]};RMQ问题可以做到O(n)的预处理,O(1)的查询复杂度;以下JAVA代码是O(nlogn)的预处理,O(1)的查询复杂度;参考文献:《算法竞赛入门经典训练指南》P197,刘汝佳,陈锋package ProgrammingContest;public cl原创 2012-11-14 06:51:45 · 1063 阅读 · 0 评论 -
Timus 1791 汽车过桥的问题
原题地址 http://acm.timus.ru/problem.aspx?space=1&num=1791中文地址http://www.51nod.com/question/index.html#!questionId=705一座桥,一辆车通过的时间是1分钟,同一时间只能有1辆车在桥上,桥的一边有N辆车排队,另一边有M辆车排队。每辆车有个开始排队时间Ti,和从排队开始一直到到达对原创 2012-11-02 22:13:16 · 741 阅读 · 0 评论 -
利用位运算枚举所有子集
用整数表示集合,某位为1表示对应元素被选取,在此规则下枚举所有子集的代码:public class TraverseSubSet { public static void ascending(int x) { for ( int i=0; ; i=(i-x)&x ) { System.out.printf("%h ", i); if ( i == x ) break;原创 2012-11-12 22:18:46 · 3141 阅读 · 0 评论 -
简单洗牌算法
一个简单高效的洗牌算法,C代码。#include #include #include /* * 每次随机抽取一张牌放入数组后部 */void shuffle(short *poker, short len) { int i; srand((unsigned)time(NULL)); for ( i=len-1; i>=1; i-- ) { int k = rand原创 2012-10-21 21:10:31 · 452 阅读 · 0 评论 -
Jurassic Remains,NEERC 2003,中途相遇法
给定n个大写字母组成的字符串,选择尽量多的串,使的每个大写字母都出现偶数次。原题:http://neerc.ifmo.ru/past/2003.html。参考文献:《算法竞赛入门经典训练指南》P57,刘汝佳package ProgrammingContest;import java.util.TreeMap;public class Jurassic_NEERC_2003原创 2012-11-11 18:09:48 · 781 阅读 · 0 评论 -
最大流算法
单源点单汇点的最大流算法,C++实现例子一枚。/* * Graph.cpp * * Created on: 2013-1-18 * Author: qichi */#include "Graph.h"#include #include /* * DAG */Graph::Graph(int n, int s, int t) { m_nVertex =原创 2013-01-19 11:03:29 · 592 阅读 · 0 评论