![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
高效算法
AC_Arthur
Die luft der Freiheit weht
展开
-
HDU 1007 Quoit Design(分治)
题目链接:点击打开链接思路:经典的分治法, 网上讲解很多我就不多说了, 这是nlognlogn复杂度, 大多数情况是够用的。。优化了一下排序函数, 跑了780ms细节参见代码:#include #include #include #include #include #include #include #include #include #include #inc原创 2017-01-17 22:23:37 · 499 阅读 · 0 评论 -
HDU 5607 graph(矩阵优化+概率DP)
该题很容易想到求概率的转移方程:用d[i][j]表示第i原创 2016-01-13 11:55:35 · 1333 阅读 · 0 评论 -
POJ 3233 Matrix Power Series(矩阵优化)
题目链接:点击打开链接题意:求S[k] = A + A^2 + ..... + A^k利用矩阵快速幂可以很快的求出A矩阵的k次方, 但是该题是求和, 如果还按照原来的方法, 将要计算k次, 复杂度无法承受。我们可以构造一个矩阵 (A 0) (E E)此时令S[k] = E + A + A原创 2016-01-12 20:03:17 · 1285 阅读 · 0 评论 -
POJ 3734 Blocks(矩阵优化+DP)
题目链接:点击打开链接题意:个n个方块涂色, 只能涂红黄蓝绿四种颜色,求最终红色和绿色都为偶数的方案数。该题我们可以想到一个递推式 。 设a[i]表示到第i个方块为止红绿是偶数的方案数, b[i]为红绿恰有一个是偶数的方案数, c[i]表示红绿都是奇数的方案数。那么有如下递推可能:递推a[i+1]:1.到第i个为止都是偶数,且第i+1个染成蓝或黄;2.到第i个为止红绿恰有一个是原创 2016-01-12 18:35:46 · 1847 阅读 · 0 评论 -
BNUOJ 51275 道路修建 Large(并查集)
题目链接:点击打开链接题意:见链接。(中文题)思路:该题与普通并查集的不同之处在于,需要查询两个点最早联通的时刻。 我们不妨在结点上维护一些信息:假设结点v, 那么维护ans[v]表示v到父亲结点的时间。 然后查询的时候, 考虑到并查集是一个树形结构, 如果两个顶点联通, 两个顶点之间有唯一路径, 路径上边的最大值就是了。因为要维护这个关系, 所以显然不能路径压缩, 因为那样会破坏结原创 2016-02-10 14:40:11 · 1732 阅读 · 0 评论 -
POJ 2886 Who Gets the Most Candies?(树状数组+二分)
对于可以被i整除的数的个数, 我们可以通过枚举每一个数的倍数, 预先处理出来。该题直接模拟就好, 因为每次都一定有一个人出队, 所以要枚举n次 , 对于每次, 要计算具体是哪个人出队, 这个可以用数学推导很快的算出来是当前队列的第几个人, 要找到这个人我们可以用二分+树状数组来优化算法。 复杂度O(n*logn*logn)细节参见代码:#include#include#incl原创 2015-12-26 10:43:05 · 932 阅读 · 0 评论 -
POJ 2828 Buy Tickets(树状数组)
题目链接:点击打开链接题意:给n个人依次插队的情况, 要求求出最终的队伍情况。该题可以用树状数组很方便的维护。如果从前向后扫的话, 每次插队都会影响这个人后面的情况, 所以我们可以倒着进行, 那么最后一个人的位置就是最终位置, 对于前面的人的位置, 只受后面人的影响, 所以等价于其最终位置是第pos[i]+1个空位。 那么也就是说要快速的找到第pos[i]+1个空位。 显然,原创 2015-12-24 20:47:36 · 858 阅读 · 0 评论 -
Codeforces Round #320 (Div. 1) C. Weakness and Poorness(三分)
对这个数列中的每一个数减去一个相同的数字, 其最大连续和会呈现出单峰函数的现象, x过大或者过小都不行, 那么处理方法显然是三分。由于该题不是直接三分的答案, 因此三分出的x虽然精度在答案范围内, 但是求出的最大连续和却不一定满足精度。二分或三分浮点数时, 最稳妥的方法是根据数据范围自己设置二分或三分的次数, 这样使得精度可以最大化的精确。细节参见代码:#include#incl原创 2015-12-07 20:17:44 · 837 阅读 · 0 评论 -
1455 - Kingdom(并查集+线段树区间加减)
题目链接:点击打开链接题意:给你n个点,m次询问,每次询问有两种:1. 将城市v和u用一条道路连接起来2.询问用一条水平线能穿过多少个州和这些周中包括的城市数。由于水平线一定是v.5的形式,所以不妨将y坐标乘以2再建立线段树,建两棵线段树,一棵维护大洲的数量,一棵维护城市数。 合并问题交给并查集就好了。另外值得一提的是,对于线段树区间加减这个问题, 其处理方法大家应该更深入原创 2016-01-25 15:25:11 · 1366 阅读 · 0 评论 -
HDU 5493 Queue(二分+树状数组)
题目链接: 点击打开链接题意:有n个人排队,每个人都有一个独一无二的身高,告诉你每个人的身高和他前面或者后面的比他高的人的个数(到底是前是后是未知的)。 要求你还原原来的队列,并且字典序最小。思路: 因为要求字典序最小, 我们可以先按照身高从小到大排序,假设当前到了第i高的人, 他前面或者后面有k个人, 那么他前面的所有人都比他矮, 比他高的还有n-i个人,那么假设他前面还有p个空位,原创 2015-12-23 22:39:29 · 1489 阅读 · 0 评论 -
2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest F. Gourmet and Banquet(贪心+二分)
该题是一道比较典型的贪心+二分, 题目中已经加深提示了吃每个菜的时间要一样, 那么这个时间到底是多少呢? 我们很自然的想到了要用二分来加速算法。所以主体框架就是二分这个吃每道菜的时间, 然后问题的关键是如何判断到底能不能满足要求。 处理区间问题, 我们可以采取贪心的思想,为了给后续的菜留出尽量多的空间,我们可以按照区间右端点从小到大排序, 但是区间覆盖情况很复杂,所以我们不妨牺牲一些时间原创 2015-12-05 20:33:48 · 955 阅读 · 0 评论 -
Codeforces Round #340 (Div. 2)题解
题目链接:点击打开链接这次的比赛比较简单, 有些坑点, 主要是考思维的严密性。。。比赛时做出了前4道, 都没有什么算法, 最后一道的通用解法是莫队算法, 现在还不会, 今天就补上。终测挂了C,原来是漏了枚举第一个半径为0的情况, 太失误了。A. Elephant原创 2016-01-24 14:02:14 · 851 阅读 · 0 评论 -
ACM 2015 亚洲区域赛北京赛区A题(二分)
该题方法就是二分, 二分R,然后在判断函数中判断在枚举点左边的绿洲面积。 这样做的复杂度是O(nlogR)。但是一开始WA了一发,后来才发现原来是因为有这样的数据:一块很大的沙漠中只有一个边长为1的小正方形绿洲。这样的数据答案是R。 所以我二分出来之后再向右推一下,直到不符合条件为止。下面是我AC代码, 二分求的上界,求下界应该更快,请读者自己实现。细节参见代码:#includ原创 2015-11-16 22:42:20 · 1166 阅读 · 0 评论 -
HDU 5592 ZYB's Premutation(二分+树状数组)
昨晚有事没打BC,今天补一补, 这是昨晚第三题,对于一个1~n的序列, 告诉我们每个数前面有多少个比他大的数, 要求我们还原序列。不难发现, 如果我们倒着看的话, 假设当前第i个数是ans[i], 它前面有a[i]个比他大的数, 那么他就是删除后面已经求出的数字后的数组中第a[i]+1大的数。不难想到,将原序列的数当作树状数组的下标, 值为1, 这样就能利用bit快速求出比当前数大的数字还原创 2015-12-06 13:25:40 · 1351 阅读 · 4 评论 -
Codeforces Round #299 (Div. 1) A. Tavas and Karafs(二分)
该题数据量很大, 需要用二分加速算法。题意比较难懂: 给你一个无穷项等差序列, 有n个查询, 对于每个查询, 有三个数 l, t, m, 每次从第l个数之后的数种选择最多m个数使得他们的值减一, 经过最多t次, 求一个最大的r, 使得从l到r所有数都减为0。显然这是一个递增序列, 那么我们直接二分答案就行了 。 如果满足这段序列求和 另外还学到了一个二分上界的好姿势。细节参见原创 2015-12-21 10:40:51 · 780 阅读 · 0 评论 -
POJ 2528 Mayor's posters(线段树区间修改+离散化)
题目链接:点击打开链接题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报。该题是线段树区间修改+离散化的应用。不难想到, 每次对一个最长10^7的线段进行线段树的区间修改, 最后统计。线段树的复杂度是log10^7, 应该不会超时, 但是会超内存。 所以想到要离散化, 将区间端点值有映射成一个尽量小的值。但是该题求的是覆盖情况, 如果按照单纯的点对点的离散化, 那原创 2016-01-02 11:29:25 · 1479 阅读 · 0 评论 -
Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks(矩阵优化DP)
题目链接:点击打开链接题意:给n个数作为一个块,有b个块,从其中若干个中选择数,每个块只能选一个数,最后组成一个数模x等于k的方法数。思路:很容易想到这样一个DP方程 : 用dp[i][j]表示现在i位,余数是j。那么dp[i + 1][(j * 10 + k) % x] = dp[i][j] * cnt[k],k是指枚举放1~9中哪一位。因为b特别大,显然要矩阵优化,知道了DP方程,原创 2016-02-01 14:45:46 · 1292 阅读 · 0 评论 -
8VC Venture Cup 2016 - Elimination Round E. Simple Skewness(枚举+三分)
题目链接:点击打开链接题意:给你n个数, 要求选若干个数, 使得这些数的平均数减去中位数尽量大。思路:由于该题没有顺序问题, 排好序之后我们可以枚举中位数, 可以证明, 奇数个数一定比偶数优,然后三分中位数左右区间长度x(数的个数), 在中位数的右边选最大的x个数, 在左边也选最大的x个, 这样, 随着区间长度的增加, 平均数将先增大后减小, 或者一直减小,或者一直增大。为什么呢? 假原创 2016-02-18 11:20:06 · 1651 阅读 · 2 评论 -
ZOJ 3635 Cinema in Akiba(二分+树状数组)
题目链接:点击打开链接题意:n个人轮流做到座位上, 第i个人做到第a[i]个空座上, 求最终每个人的座位情况。思路:经典水题, 二分套树状数组。细节参见代码:#include#include#include#include#include#include#include#include#include#include#include#include#incl原创 2016-03-04 15:06:11 · 1134 阅读 · 0 评论 -
Codeforces Round #388 (Div. 2)D. Leaving Auction(水题呀?)
题目链接:点击打开链接思路:我们只要把每个人竞价的最大值存起来, 并且把每个人的所有竞价维护在一个有序数组(方便二分), 对于一组询问, 我们从大到小遍历这k个数,把不在这k个数的最终竞价最大的两个人找到(复杂度O(K)), 然后在竞价最大的那个人的set里二分第二大的人的竞价最大值就行了。细节参见代码:#include #include #include #include原创 2016-12-20 22:02:50 · 937 阅读 · 0 评论 -
Codeforces Round #389 Technocup 2017 E. Santa Claus and Tangerines(二分+DP)
题目链接:点击打开链接思路:我们二分答案, 那么这就变成了一个二分求下界的问题了。 关于判定我采用了一种记忆化搜索的递归方式, 简单证明了一下应该可以达到log的复杂度。细节参见代码:#include #include #include #include #include #include #include #include #include #include原创 2016-12-25 21:07:07 · 694 阅读 · 0 评论 -
51NOD 1640 天气晴朗的魔法(二分+最大生成树)
题目链接:点击打开链接思路:我们二分最大的边, 这显然是符合二分性质的, 然后使得边权和最大用最大生成树就行了。细节参见代码:#include #include #include #include #include #include #include #include #include #include #include #include #include原创 2016-11-30 21:20:08 · 565 阅读 · 0 评论 -
Vijos P1988 自行车比赛(treap)
题目链接:点击打开链接思路:如果我们判断第i个人是否能第一, 只需要把尽量小的分值给分数最大的人, 如果有人超过了他, 就不能得第一。我们可以把n个人排序, 让2~n个人分别加上n-1~1, 用treap维护最大值。 转移到下一个人的时候, 只需要把下一个人的加分加到当前这个人上就行了。PS:用treap的原因是set被卡了。 吐槽:set太慢了。细节参见代码:#inclu原创 2016-11-03 21:31:15 · 777 阅读 · 0 评论 -
ZOJ 3216 Compositions(矩阵优化DP)
题目链接:点击打开链接思路:ZOJ挂了, 理论AC一下。用d[i]表示数i的拆分方案。 转移是个难点, 我们可以考虑转移到d[i-1]表示对于当前这个拆分出的数进行+1修改, 转移到d[i-k]表示之前拆分的数不变了, 新增加一个拆分数k。然后构造矩阵就很简单了。原创 2016-10-21 20:27:46 · 782 阅读 · 0 评论 -
Ural 1542. Autocompletion(二分)
题目链接:点击打开链接思路:因为单词最长15, 我们把每个单词不同长度的前缀存起来, 排序之后二分即可, 复杂度O(nlogn)细节参见代码:#include #include #include #include #include #include #include #include #include #include #include #include原创 2016-10-11 16:05:03 · 493 阅读 · 0 评论 -
UVA 501 - Black Box(二分 + 树状数组 + 离散化)
题目链接:点击打开链接思路: 该题虽然是求区间第k小, 但是实际上是不需要用到复杂的数据结构的, 我们只需要用树状数组来维护就行了, 因为以值作为树状数组下标, 那么这就是一个天然的单调区间, 用二分来查找就行了。 另外就是要离散化一下。细节参见代码:#include #include #include #include #include #include #includ原创 2016-04-30 17:12:51 · 3680 阅读 · 0 评论 -
Codeforces Round #250 (Div. 2) (D. The Child and Zoo(并查集))
题目链接:点击打开链接题意:给你一个n个点, m条边的图, 每个点有一个点权值, 我们定义f(p, q)表示p点到q点的一条路径, 要求这条路径上的最小点权尽量大, 其值等于最小点权值。 求任意一对点的f值之和除以n * (n - 1) , 即平均值。思路: 其实转化一下, 就是要先求最大生成树, 那么路径一定在树种, 且唯一。 那么我们从大到小来, 每次将两个集合合并的时候, 那么A原创 2016-03-11 19:46:24 · 1305 阅读 · 0 评论 -
UVA 11389 - The Bus Driver Problem(二分or暴力)
题目链接:点击打开链接题意:n个老司机, n个下午路线,n个晚上路线, 要求给每个老司机分配一个下午路线和一个晚上路线, 使得每条路线恰好被分配给一个老司机, 且支付的加班费最少。思路:n太小了, 直接n^2暴力都行, 当然了可以用二分加速一下。 从小到大排序后, 从下午路线最短的开始, 找第一个大于等于d - a[i]的晚上路线, 如果都比d - a[i]小, 那么选择当前最大的一条,为原创 2016-02-26 14:06:13 · 1436 阅读 · 1 评论 -
Codeforces Round #345 (Div. 2) (D. Image Preview(二分))
题目链接:点击打开链接题意:给你n个照片, 从第一个照片开始看, 如果一张照片是'w', 那么要花费b时间去反转他, 否则不用反转, 看一张从来没看过的照片要1时间, 从一张滑动到另一张要a时间。 如果一张照片看过, 则不用再反转, 也不用再傻1s 。 求在不超过T时间的前提下最多能看多少张。思路:首先我们可以发现, 存在折返的情况, 也就是看到一个地方返回向另一端翻照片。 但是显然最多只原创 2016-03-10 21:20:59 · 1958 阅读 · 0 评论 -
UVA 11627 - Slalom(二分)
题目链接:点击打开链接题意:你有s个滑雪器具, 每个的下滑速度不同, 从高到低有n个门, 你的水平速度最大是v,求一个下滑速度最大的能够穿过所有n个门的器具。思路:将n个器具的速度排序, 这样就成了二分查找找上界。 判断是否能穿过所有门也很简单, 只要每次维护一个能滑到的最大范围就行了。细节参见代码:#include#include#include#include#inc原创 2016-02-25 21:24:35 · 2230 阅读 · 2 评论 -
UVA 1422 - Processor(二分+优先队列+贪心)
题目链接:点击打开链接题意:有n个任务, 每个任务必须在[r,d]时间段内完成, 任务量为w, 求最小执行速度, 使得可以在规定时间内完成所有任务。思路:二分通常要和贪心搭配, 显然, d越小的, 应该优先完成, 所以我们可以用一个优先队列来维护这个信息, 然后枚举每一个时刻, 看看应该先执行那个程序。细节参见代码:#include#include#include#inclu原创 2016-02-25 12:37:50 · 1348 阅读 · 0 评论 -
UVA 12124 - Assemble(二分)
题目链接:点击打开链接题意: 给n个组件来组装电脑, 每个组件有4个属性:种类、名称、价格、品质。 要求每种组件买一个, 求在不超过预算的情况下, 品质最低的品质尽量大。思路:很显然, 二分最低品质, 然后判断是否可行, 属于二分找上界,在二分时有一个小技巧用来处理当区间相差1时的情况。细节参见代码:#include#include#include#include#incl原创 2016-02-24 00:01:37 · 1998 阅读 · 2 评论 -
HDU 4302 Holedox Eating(multiset)
题目链接:点击打开链接题意:有个吃货在坐标为1~L的线段上, 开始在0位置, n个操作, 0 x 表示在x位置放一个蛋糕, 1 表示这个吃货会吃掉离她最近的一个蛋糕。 如果在左右两边都有离他最近的,就按照上次的方向吃。思路:用multiset维护蛋糕的位置, 用二分查找加速算法, 乱搞即可。细节参见代码:#include#include#include#include#in原创 2016-03-06 20:42:06 · 668 阅读 · 0 评论 -
HDU 2335 Containers(暴力枚举)
题目链接:点击打开链接题意:n个40X8的箱子, 要求建一个矩形场地来放这些箱子, 箱子间有已知大小的间隙, 最高可以放5层。 求场地的最小面积, 在此基础上尽量方。思路:设场地x列,y行, 那么x*y == (n+4)/5 所以x不会超过sqrt(n), 所以枚举x求y就行了。比赛的时候考虑到随着x的增加, 答案先变小后变大, 所以三分的, 但是样例都过不了, 后来才注意到是5层。原创 2016-02-19 15:50:38 · 1134 阅读 · 0 评论 -
HDU 5596 GTW likes gt(multiset)
该题其实只需要利用multiset维护一下就可以了。根据题意, 利用题目特点, 可以发现, 如果正着枚举的话, 前面的对后面的会产生影响, 但是, 如果我们倒着枚举就可以避免这个情况。所以我们不妨先记录每个时间点释放魔法的次数, 然后倒着枚举, 这样当前这个数的能力值就是v+res (res为当前附加的魔法值, 因为后面时间增加的魔法,对于前面时间也一定增加了)。 所以,原创 2015-12-13 11:30:42 · 814 阅读 · 0 评论 -
HDU 2438 Turn the corner(三分)
昨天个人赛的题目,没有做出来,今天学了一下三分,其实很简单,就是用来求一个凸函数或凹函数的最值的方法。大家可以看这个博客,讲的很清楚 :点击打开链接然后该题就是设拐的角度为自变量,范围0~pi/2 。 然后三分就行了。 这样就可以求出最大值是多少了,然后如果最值比y小,就可以过去,否则不可以。值得一提的是,队里有人用暴力过了,他将拐点设在了车的中间(l/2处),然后暴力的转角,每次原创 2015-10-31 10:49:48 · 670 阅读 · 0 评论 -
Asia Regional Contest, Tokyo,Problem C Shopping
贪心。不难证明,如果两个区间有交集,那么最好的方法是走完这些区间的并再掉头。 也就是说,处理出所有相交的区间组成一个更大的区间,然后对于这些区间,答案要加上两倍的区间长度。 然后最后再加上整条街的长度即可。细节参见代码:#include#include#include#include#include#include#include#include#include#原创 2015-11-16 22:32:55 · 503 阅读 · 0 评论 -
11549 - Calculator Conundrum(水题)
很简单的水题,显然是有循环的,只要循环回出现过的数字就不必再继续平方了。细节参见代码:#includeusing namespace std;typedef unsigned long long ll;const int maxn = 1000;ll T,n,m,k;int main() { scanf("%d",&T); while(T--) {原创 2015-09-08 19:27:36 · 550 阅读 · 0 评论 -
11462 - Age Sort (排序)
该题特点是输入量巨大,特别耗费时间,而且输入数据25MB之多,远远超出了内存限制。但是容易发现,每个数的值属于1~100,范围很小, 所以我们可以用计数排序的方法。细节参见代码:#includeusing namespace std;typedef long long ll;const int INF = 1000000000;const int maxn = 105;int n原创 2015-09-05 17:32:21 · 669 阅读 · 0 评论 -
11078 - Open Credit System(简单题)
一道简单题。细节参见代码:#includeusing namespace std;const int INF = 100000000;int T,n,m,a;int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); int maxv = -INF, ans = -INF;原创 2015-09-08 17:31:07 · 642 阅读 · 0 评论