随笔分类 -  ACM

摘要:链接:http://acm.hdu.edu.cn/showproblem.php?pid=4815【题意】 n个题目,每题有各自的分数,A有50%的概率答对一道题目得到相应分数,B想要在至少P的概率上总分不低于A,问B至少要得到多少分。【分析】 最简单粗暴的做法是算出每个可能得到的总分的概率,原问题可以转化成在概率和=P。 但是计算所有可能的概率的复杂度是O(2n),不能满足我们的需求。细心分析可以发现问题可以分离出重叠子问题:f[i][j]表示前i个题目得到j分数的概率,于是类似背包问题,可以找出递推式: f[i][j]=f[i-1][j]*0.5 (score... 阅读全文
posted @ 2014-02-05 18:26 wuminye 阅读(539) 评论(0) 推荐(0)
摘要:链接:http://codeforces.com/problemset/problem/388/B【题意】 给出一个整数K,构造出刚好含有K条从1到2的最短路的图。【分析】 由于是要自己构造图,当然构造的方法很多了,需要考虑简单性和可行性。出于简单考虑,图中从1到2的所有路径都是最短路,为了保证路径长度一样,在构图时就需要分层次,使得每一层的点距离上一层的点的距离都是一个单位。 那么如何使得路径条数刚好为K呢,这里涉及到相邻层次的点的链接方式。比如说每个点和上一层的所有点都有链接,那么这样总的路径数就是每层点的个数乘起来,但是这很难保证乘起来的值刚好是K,于是想到进制数的方法,可以构造出不同底 阅读全文
posted @ 2014-02-05 09:53 wuminye 阅读(644) 评论(0) 推荐(0)
摘要:【简介】 解决LCA问题的倍增法是一种基于倍增思想的在线算法。【原理】 原理和同样是使用倍增思想的RMQ-ST 算法类似,比较简单,想清楚后很容易实现。 对于每个节点u , ancestors[u][k] 表示 u 的第2k个祖先是谁。很容易就想到递推式:ancestors[j][i]=ancestors[ancestors[j][i-1]][i-1]; 根据二进制原理,理论上 u 的所有祖先都可以根据ancestors数组多次跳转得到,这样就间接地记录了每个节点的祖先信息。 查询LCA(u,v)的时候: (一)u和v所在的树的层数如果一样,令u'=u。否则需要平衡操作(假设u更深), 阅读全文
posted @ 2014-01-24 14:25 wuminye 阅读(2035) 评论(0) 推荐(0)
摘要:【简介】 解决LCA问题的Tarjan算法利用并查集在一次DFS(深度优先遍历)中完成所有询问。换句话说,要所有询问都读入后才开始计算,所以是一种离线的算法。【原理】 先来看这样一个性质:当两个节点(u,v)的最近公共祖先是x时,那么我们可以确定的说,当进行后序遍历的时候,必然先访问完x的所有子树,其中包含u、v,然后才会返回到x所在的节点。这个性质就是我们使用Tarjan算法解决最近公共祖先问题的核心思想。 如上图所示,找出根节点到u得关键路径P ,已遍历的点位于路径P中某个点的子树中,当遍历到u时v已遍历过(u的子树已遍历完),那么v必然存在于子树pk中,此时LCA(u,v)就等于现在v所 阅读全文
posted @ 2014-01-20 16:40 wuminye 阅读(1188) 评论(0) 推荐(0)
摘要:链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586【题意】 给出一个N 个和N-1条边的连通图,询问任意两点间的距离。N 3 #include 4 #include 5 #include 6 using namespace std; 7 int n,m; 8 struct edge 9 { 10 int d,v,next; 11 edge(){} 12 edge(int _d,int _v,int _next) 13 { 14 d=_d;v=_v;next=_next; 15 ... 阅读全文
posted @ 2014-01-19 20:37 wuminye 阅读(359) 评论(0) 推荐(0)
摘要:【简介】 LCA(T,u,v):在有根树T中,询问一个距离根最远的结点x,使得x同时为结点u、v的祖先。 RMQ(A,i,j):对于线性序列A中,询问区间[i,j]上的最值。见我的博客---RMQ ---- ST(Sparse Table)算法。【LCA算法】 解决LCA问题有多种算法,一种是离线的 Tarjan算法 ,还有在线的倍增法 ,还有就是转换为RMQ问题的在线算法。【LCA转化为RMQ】 (一)对有根树T进行DFS,将遍历到的结点按照顺序记下,我们将得到一个长度为2N – 1的序列,称之为T的欧拉序列F 。 (二)每个结点都在欧拉序列中出现,我们记录结点u在欧拉序列中第一次出现的位. 阅读全文
posted @ 2014-01-19 15:30 wuminye 阅读(727) 评论(1) 推荐(1)
摘要:【概述】 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j=n) break; 9 f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);10 } 查询:1 int query(int s,int e) //查询区间[s,e]的最值2 {3 int k=(int)((log(e-s+1.0)/log(2.0)));4 return max(f[s][k],f[e-(1<<k)+1][k]);5 } 阅读全文
posted @ 2014-01-18 10:49 wuminye 阅读(2200) 评论(3) 推荐(0)
摘要:题目链接:http://202.121.199.212/JudgeOnline/problem.php?id=1716【题意】 1到N的区间,一种操作让编号从a到b的数变为z,但不会低于2,问多次操作后大于2的数减2后的和为多少。【分析】 本来这题可以用线段树模拟过的,但是这里的N非常大,达到109,开个一维数组就会爆内存,更何况开个线段树。 分析题目后不难发现最后的一个操作一定生效,之前的操作如果有涉及之后操作区间的部分就会失效。根据这条性质,从操作的后面往前扫描,更新区间内的元素,如果元素被更新过就忽略,这样根据所有元素更新后的值就能算出结果了。如果用元素标记的方法一来时间复杂了,二来内存 阅读全文
posted @ 2014-01-04 22:24 wuminye 阅读(919) 评论(0) 推荐(0)
摘要:题目链接:http://www.codechef.com/JAN14/problems/SEAGRP【题意】 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1.【分析】 从结论入手,每个点的度恰好为1,那么就意味着每个点只能连接一个点,这样问题就转化为图中的点能否刚好两两配对。 对于奇数个点肯定是不行的,因为一定存在一个点不存在与之配对的点。 如果点是偶数,那么就要求这个图的最大匹配,看匹配树是否为点数的一半。 求匹配的方法和二分图类似,不断找增广路更新匹配数就好了。【代码】 第一次手写增广路代码~写的时候忘记判断增广路是否重点了于是WA了,还好后来想到了。 1 #inc 阅读全文
posted @ 2014-01-04 10:07 wuminye 阅读(562) 评论(0) 推荐(0)
摘要:题目链接:http://codeforces.com/problemset/problem/379/D【题目大意】 告诉你初始字符串S1、S2的长度和递推次数k, 使用类似斐波纳契数列的字符串合并的递推操作,使得最后得到的字符串中刚好含有x个"AC",现在要你构造出满足条件的S1和S2。【分析】 最终结果中有些"AC"可能是应为在合并时一个字符串的尾部和另一个字符串的首部合并而成,这就跟原始字符串的首尾字符有关,不同的情况在K次递推后多产生的"AC"数是不同的,所以这里既要枚举下初始串的首尾字符,计算出因合并产生的"AC&q 阅读全文
posted @ 2014-01-01 10:40 wuminye 阅读(331) 评论(0) 推荐(0)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=4424【题目大意】 给你N个点和N-1条边的连通图,也就是说任意两点间的路径是唯一的。每条边有个权值,从一点到另一点的最大流量是路径中所有边中权值的最小值。要你找一个点,使得这点到剩下所有点的最大流量之和最大,求这个最大流量和。【分析1:动态规划 】 假设现在有两个点的集合S1和S2,添加的一条边可以使得这两个集合连通起来,要求最大的流量之和,那么只有两种情况:1、选取的中心点在S1中;2、选取的中心点在S2中。设S中其最小权值的边为E,它连接S1、S2,假设中心点在S1,那么S2中所有的点要连接到中心点必然 阅读全文
posted @ 2013-08-28 15:02 wuminye 阅读(342) 评论(0) 推荐(0)
摘要:【题意】这个函数是给A求B的,现在给你B,问你是否能有A的解存在。【2-SAT解法】 对于每个A[i]的每一位运行2-sat算法,只要跑到强连通就可以结束,应为只要判断是否有解,后面拓扑求解就不需要了。构图和算法思想和基本的2-sat一致,详见我的2-sat博文。 1 #include 2 #include 3 inline int min(int a,int b){return a>b?b:a;} 4 struct edge 5 { 6 int v,next; 7 edge(int d=0,int n=-1):v(d),next(n){} 8 vo... 阅读全文
posted @ 2013-08-22 12:32 wuminye 阅读(772) 评论(0) 推荐(0)
摘要:在实际问题中2-SAT问题在大多数时候表现成以下形式:有2N个物品,每2个分为一组,现在要选出N种物品,同组物品不能同时选取,问你在满足题目要求的情况下能不能按规则选出物品,如果可以,那么可能的方案是什么。 在本质中是这样的:对于一个合取范式,是否有一种输入使得他的输出是1,具体点就是类似这样的布尔表达式(x1 or x2 or x3)and(x3 or x4)and(not x1 or x5)对于所有的x是否有一种01取值,使得最后的结果是1。【建模】 建立一个2N阶的有向图,其中的点分为N对,每对点表示布尔序列A的一个元素的0、1取值(以下将代表A[i]的0取值的点称为i,代表A[i]的. 阅读全文
posted @ 2013-08-22 10:47 wuminye 阅读(327) 评论(0) 推荐(0)
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890【题意】 给你n个数,每次将第i个位置到第i大的数所在位置之间的数进行翻转,模拟一种排序的操作,输出的是第i次操作第i大的数所在的位置。【分析】 这题和2012天津现场赛的K题类似,用Splay Tree 来记录节点间的相对左右关系,树的中序就是原数列。每个节点记录以自己为根的子树有多少个节点,这样就可以很快知道一个数的左边右多少树了。每次操作后要删除第i大数的节点,根据题目要求元素要用stable_sort排序,并记录节点指针地址,这样的话第i个答案就是i+path[i-1].t->l 阅读全文
posted @ 2013-08-16 16:16 wuminye 阅读(367) 评论(0) 推荐(0)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=4441题意:对于一个序列,每次有三种操作 insert pos 表示在pos插入一个数,这个数是最小的正数没有在序列中出现的。而且还要在某个位置插入他的相反数,使得这个序列满足队列的出入顺序(正表示进,负表示出) remove num 表示在序列中把num以及-num两数去掉 query num 把num与-num之间的数求和输出 这题我本来实在是没有思路,看起来像维护一个线段树,这样求和好办,但是序列的长度是会变的,而且元素的绝对位置是会变的,线段树就无法解决了。 通过这题我才了解了一个新的数据结构:Sp. 阅读全文
posted @ 2013-08-14 23:45 wuminye 阅读(448) 评论(0) 推荐(0)
摘要:费马小定理是初等数论四大定理(威尔逊定理,欧拉定理(数论中的欧拉定理,即欧拉函数),中国剩余定理和费马小定理)之一,在初等数论中有着非常广泛和重要的应用。实际上,它是欧拉定理的一个特殊情况。 其内容为: 假如p是质数,且GCD(a,p)=1,那么 a^(p-1) ≡1(mod p)(假如p是质数,且a,p互质,那么 a的(p-1)次方除以p的余数恒等于1) 证明:大数取余的公式 (a*b)%mod =(a%mod * b%mod) %mod, 设P为素数 那么 (a*k) %p =(a%p*k) % P [1 (a^(p-1))%p=1 证毕。 用费马小定理的逆命题可以来判定素数,但是其逆命. 阅读全文
posted @ 2013-08-12 15:57 wuminye 阅读(3211) 评论(0) 推荐(0)
摘要:Splay Tree 是二叉查找树的一种,它与平衡二叉树、红黑树不同的是,Splay Tree从不强制地保持自身的平衡,每当查找到某个节点n的时候,在返回节点n的同时,Splay Tree会将节点n旋转到树根的位置,这样就使得Splay Tree天生有着一种类似缓存的能力,因为每次被查找到的节点都会被搬到树根的位置,所以当80%的情况下我们需要查找的元素都是某个固定的节点,或者是 一部分特定的节点时,那么在很多时候,查找的效率会是O(1)的效率!当然如果查找的节点是很均匀地分布在不同的地方时,Splay Tree的性能就会变得很差了,但Splay Tree的期望的时间复杂度还是O(nlogn. 阅读全文
posted @ 2013-08-12 11:35 wuminye 阅读(410) 评论(0) 推荐(0)
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4435题目大意是给出N个二维坐标点代表N个城市,让你选择几个城市建加油站,使得能从1号城市出发遍历所有城市再回来,并且每加一次油的行驶距离为D,不能让车抛锚了。建立一个加油站需要一定的花费,现在要你求花费最少的建站方案。 题目有个突破口是在第i个城市建加油站的花费是2(i-1),花费刚好就是个N位的二进制,如果在第i位建站,费用比前i-1个城市都建站还高,所以这里可以用贪心,编号越高的城市能不建站就不建站,这样就能保证花费最小。确定能不能建站的方法是如果该城市不建站,从1出发存在一个路径使得能遍历所 阅读全文
posted @ 2013-08-08 12:14 wuminye 阅读(329) 评论(0) 推荐(0)
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4433这是一道2012年ACM天津赛区现场赛的题目,大意是给出两串数字,求用最少的转换次数将一串(A)变为另一串(B)。转换规则是:可以将连续的1到3位数字都加一或者减一(0-9的数字是循环的,0减一变9,9加一变0)本题的数字串的长度最大有1000,光用搜索是不行的了,正解是DPDP[i][j][k]表示前i-2个数字与目的串的相同,且第i-1位为j , 第i 位为k 的最小变换次数。那么状态的转移就是 DP[i][j][k]=min{DP[i-1][ X ][ Y ]+dis(A[i],K)} 阅读全文
posted @ 2013-08-05 16:43 wuminye 阅读(356) 评论(0) 推荐(0)
摘要:【题目大意】 有多个珠子,给出部分珠子之间的相对上下位置和间距,问你这些珠子在满足给出的条件下,是否能把珠子排列在一条竖直直线上,如果能,求出每个珠子距离最高的珠子的距离,珠子的位置可重叠。【分析】 可以根据珠子的位置关系建立一张有向图,A->B 为A比B高,权值为之间的距离。可以发现必须满足下列三种情况: 1、图有连通;无法比较出不同连通分支的上下关系。 2、有向图没有环;根据位置的传递关系,不可能自己比自己低。 3、如果从A到B有多条路径,路径的长度都应该一样;要不然B的位置关系就会有二义性。 我本来的想法是按顺序验证上面三条规则,把有向图转为无向图判联通,用拓扑排序判环,用DFS来 阅读全文
posted @ 2013-07-10 17:08 wuminye 阅读(606) 评论(0) 推荐(0)