上一页 1 ··· 8 9 10 11 12 13 14 15 16 ··· 85 下一页
  2012年8月26日
摘要: HDU_3338 至于具体怎么建图在其他博客里可以找得到(网络流的题解实在写起来比较费劲,所以这次就偷懒一下了……),不过值得一提的是,不必像大多数博客说的那样每个空白格子既要向管辖行的run连条边又要向管辖列的run连条边,实际上只要把对应的管辖行的run和对应的管辖列的run连条边就可以了,这条边就代表了这个空白格子,流过的流量就是这个格子要填的数。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 20010#define MAXN 110#define MAXM 600 阅读全文
posted @ 2012-08-26 22:00 Staginner 阅读(267) 评论(0) 推荐(0) 编辑
摘要: HDU_3251 这个题目可以用最小割来做,原图上的边的费用当成容量,另外将每个可以选择的点和T连起来,容量为点权,这样做完最小割之后就会将点分成两个集合,一部分是S出发能到达的,记作S集合,另一部分是能够到达T的点,记作T集合。这样如果可以选择的点属于了S集合,那么就必然要断开和T连的边,表示如果不选这个点那么相对与最大收益来讲就要减去这个点的点权,另外连通S集合和T集合的边也都要断开,表示为了从1出发不能到达T集合中选择的点,所需要付出的代价。 于是最后用理想的最大收益减去最小割就是可能获得的最大收益了。 打印割边的时候,可以先从S出发沿非满流的边走,能够走到的点都视作S集合中的点,... 阅读全文
posted @ 2012-08-26 16:45 Staginner 阅读(363) 评论(0) 推荐(0) 编辑
摘要: HDU_3068 因为做中欧区域赛的题目时,题解有提到Manacher's ALGORITHM,于是就学了一下并找了两个题练练手,一个是HDU_3068还有一个是URAL_1297。推荐一篇讲这个算法讲的感觉挺清楚的博客:http://www.felix021.com/blog/read.php?2040。View Code // HDU_3068#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 220010int N, p[MAXD];char str[MAXD], 阅读全文
posted @ 2012-08-26 15:15 Staginner 阅读(865) 评论(0) 推荐(0) 编辑
摘要: UVALive_4977 一个贪心的思路就是我们每次喝水的时间应该尽量靠前,同时时间不能早于之间降水的时间,于是可以用线段树找到区间内第一个满足要求的点即可。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 1000010#define INF 0x3f3f3f3fint N, M, D, min[4 * MAXD], t[MAXD], pre[MAXD];void update(int i){ for(; i ^ 1; i >>= 1) min[i >&g 阅读全文
posted @ 2012-08-26 15:08 Staginner 阅读(271) 评论(0) 推荐(0) 编辑
  2012年8月24日
摘要: UVALive_4976 这个题目可以先预处理出每个点向左走一共有多少个连续下降的元素,以及向右走一共有多少个连续上升的元素,处理出这两个东西后思路基本就有了。 接下来用线段树也可以做,或者可以借鉴O(NlogN)求解最长上升子序列的方法的思想来做,但后者效率更高一些。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 200010int N, a[MAXD], s[MAXD], R[MAXD], top;void init(){ int i; scanf("%d&q 阅读全文
posted @ 2012-08-24 21:30 Staginner 阅读(535) 评论(1) 推荐(1) 编辑
摘要: UVA_11192 如果是在一维的序列上进行这些操作的话,那么线段树就可以了。不过现在题目将这些操作拓展到了二维,回想线段树的本质是二分线段,那么对于一个二维的矩阵,拓展一下就应当是四分矩阵了。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 1000010#define INF 0x3f3f3f3fint N, M, P, node;struct SegTree{ int x1, y1, x2, y2, sum, min, max, add, to, son[4], are 阅读全文
posted @ 2012-08-24 16:26 Staginner 阅读(304) 评论(0) 推荐(0) 编辑
摘要: UVA_11996 这个题目前三个操作都是典型的splay的操作,但是第四个操作之前没见过,我以前只用字典树+二分求过任意两个串的LCP,但这次是在splay上便一时间无从下手。后来看了别人的代码发现也是基于二分的,而至于如何判断二分出来的前缀是相同的,则直接用哈希值去比较了。 至于直接用哈希值判断两个字符串是否相等,我一开始也觉得很不靠谱,后来分析了一下发现虽然不靠谱但不靠谱的概率是比较小的。假定我们用一个long long的哈希值,它可以区分出2^64个不同的字符串(当然这只是极限情况,如果哈希算法不同所能表示的字符串的数量也不大相同),而题目的01串至多也就400,000位,这样即便.. 阅读全文
posted @ 2012-08-24 13:04 Staginner 阅读(585) 评论(0) 推荐(0) 编辑
  2012年8月23日
摘要: UVA_11994 这个题目思维上的障碍比较少,因为实际上都是link-cut-tree的基本的操作,还有一个更为复杂的link-cut-tree的题目——HDU_4010。 在维护路径上边的颜色的数量时,由于颜色的种类只有30个,因此可以用一个整数的30个二进制位来存储颜色的种类。#include<stdio.h>#include<string.h>#define MAXD 50010int N, M;struct Splay{ int pre, ls, rs, col, set, to, size; bool root; void pushdown(); void 阅读全文
posted @ 2012-08-23 19:24 Staginner 阅读(449) 评论(0) 推荐(0) 编辑
摘要: UVA_11997 由于K行处理起来比较繁琐,所以一个可行的思路是就当作两行处理,这样处理K-1次就可以了。 对于只有两行的情况,可以考虑怎样才能够一个一个的将和由小到大构造出来,这一点可以借助优先级队列来实现:先将两个最小的放进去,之后每次都取出和最小的那两个数,然后尝试将第一个数换成第一行的稍大一点的数后放到优先级队列中,然后再尝试将第二个数换成第二行稍大一点的数放到优先级队列中。这样从优先级队列中取出的前K个元素就是前K小的和。#include<stdio.h>#include<string.h>#include<algorithm>#define m 阅读全文
posted @ 2012-08-23 14:21 Staginner 阅读(631) 评论(0) 推荐(0) 编辑
摘要: UVA_11995 如果还可能是某个数据结构的话,就对其模拟操作,知道出现错误为止。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 1010int N, D, max[4 * MAXD], q[MAXD], s[MAXD];void init(){ for(D = 1; D < N + 2; D <<= 1); memset(max, 0, sizeof(max[0]) * 2 * D);}void update(int i){ for(; i ^ 1; 阅读全文
posted @ 2012-08-23 13:04 Staginner 阅读(222) 评论(0) 推荐(0) 编辑
上一页 1 ··· 8 9 10 11 12 13 14 15 16 ··· 85 下一页