07 2013 档案

摘要:后缀数组——处理字符串的有力工具作者:罗穗骞2009年1月 【摘要】 后缀数组是处理字符串的有力工具。后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多功能而时间复杂度也并不逊色,而且它比后缀树所占用的内存空间小很多。可以说,在信息学竞赛中后缀数组比后缀树要更为实用。本文分两部分。第一部分介绍两种构造后缀数组的方法,重点介绍如何用简洁高效的代码实现,并对两种算法进行了比较。第二部分介绍后缀数组在各种类型题目中的具体应用。 【关键字】 字符串,后缀,后缀数组,名次数组,基数排序, 【正文】一、后缀数组的实现 本节主要介绍后缀数组的两种实现方法:倍增算... 阅读全文
posted @ 2013-07-31 23:22 一生挚爱 阅读(423) 评论(0) 推荐(0)
摘要:#include #include #include #include #include using namespace std;const int maxn = 1000;const int maxm = 100000;const int inf = 10000000;struct node{ int v,flow,next;}edge[maxm];int head[maxn],dis[maxn];int id,s,t,n,m;void add_edge(int u,int v,int flow){ edge[id].v = v;edge[id].flow = flow;edge... 阅读全文
posted @ 2013-07-31 23:09 一生挚爱 阅读(188) 评论(0) 推荐(0)
摘要:由于被小孩子不喜欢的糖果的对小孩产生的效力是一样的,所以我们在网络流的时候先不考虑。1 - 源点0到1~N个糖果,容量为1,费用为02 - 根据like数组,like[i][j] == 1时在糖果j和人N+i之间建立有一条边,容量为1,费用为03*- 根据b[i]和K的值建立小孩和汇点之间的边:如果b[i] 是 K 的倍数, 说明花费b[i] / K个喜欢的糖果可以达到b[i],建立一条边,费用为K,容量为b[i] / K;否则,将这条边拆为两部分,第一部分是b[i] / K的部分,第二部分根据b[i] % K的部分。(如果b[i] % k == 0,说明b[i]是k的倍数;若b[i]... 阅读全文
posted @ 2013-07-31 22:31 一生挚爱 阅读(294) 评论(0) 推荐(0)
摘要:/*** 无向图拆点,求最大流,最大流即为割点个数。*/#include #include #include #include #include using namespace std;const int maxn = 410;const int maxm = 100100;const int INF = 200000000;struct node{ int v,flow,next;}edge[maxm];int head[maxn],dis[maxn],aug[maxn];int n,m,s,t,id;void add_edge(int u,int v,int flow){ e... 阅读全文
posted @ 2013-07-31 19:29 一生挚爱 阅读(280) 评论(0) 推荐(0)
摘要:题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2485题目要求:删除最少的点,使得源点到汇点的距离大于k思路:拆点、建图求费用小于等于k的最大流#include #include #include #include #include using namespace std;#define min(x,y) (x)que; que.push(source); while( !que.empty()){ int u = que.front(); que.pop(); vis[u] = 0; ... 阅读全文
posted @ 2013-07-31 16:27 一生挚爱 阅读(250) 评论(0) 推荐(0)
摘要:#include #include #include #include #include using namespace std;const int maxm = 50000*4;const int maxn = 110;struct node{ int v,cost,flow,next;//v表示指向的下一个顶点,a表示系数,flow表示可以过的流量}edge[maxm];int head[maxn],dis[maxn],pre[maxn],cur[maxn],vis[maxn],aug[maxn];int s,t,v,n,m,k,id,flow;void add_edge(int u... 阅读全文
posted @ 2013-07-31 16:22 一生挚爱 阅读(135) 评论(0) 推荐(0)
摘要:一开始题目没看清楚,以为是增加那条边后还有多少桥,所以就当做是无向图tarjan缩点后建树,然后求u,v的最近公共祖先,一直wa。后来再看题目后才发现边放上去后不会拿下来了,即增加i条边后桥的数量。#include #include #include #include using namespace std;const int maxn = 100100;const int maxm = 200100;struct node{ int v,next;}edge[maxm*2];int head[maxn],low[maxn],dfn[maxn],fa[maxn],stack[maxn]... 阅读全文
posted @ 2013-07-30 23:36 一生挚爱 阅读(248) 评论(0) 推荐(0)
摘要:/*** 题目要求过最少k条边的最短路*/#include #include #include #include #include using namespace std;const int maxn = 5010;const int maxm = 200010;const int INF = 1que; tmp.v = s,tmp.num = 0; dp[tmp.v][tmp.num] = 0; vis[tmp.v][tmp.num] = 1; que.push(tmp); while( !que.empty()){ now = que.front... 阅读全文
posted @ 2013-07-30 10:32 一生挚爱 阅读(288) 评论(0) 推荐(0)
摘要:#include #include #include using namespace std;const int maxn = 2100;struct node{ int v,next;}edge[maxn*maxn];int head[maxn],res[1005*1005][2],low[maxn],dfn[maxn],stack[maxn],in[maxn];int n,m,id,clock,top;void add_edge(int u,int v){ edge[id].v = v;edge[id].next = head[u];head[u] = id++;}void i... 阅读全文
posted @ 2013-07-29 20:03 一生挚爱 阅读(216) 评论(0) 推荐(0)
摘要:状态转移方程:dp[u][0] = max(dp[v][0],dp[v][1]);dp[u][1] += dp[v][0];#include #include #include #include #include using namespace std;const int maxn = 6010;vectortree[maxn];int rat[maxn],deg[maxn],dp[maxn][2];int max(int x,int y){ return x > y ? x : y;}void dfs(int u){ if(0 == tree[u].size()) { ... 阅读全文
posted @ 2013-07-29 08:55 一生挚爱 阅读(144) 评论(0) 推荐(0)
摘要:题目意思:给出n个点,m条边,边分为两种,一种是A公司的,一种是B公司的。边上有权值,问用n-1条边把n个点连起来的最小费用是多少,其中A公司的边刚好有k条。题目保证有解。题解:题目意思很简单就是求MST且A公司要有且仅有k条边在树中,刚开始做的时候用贪心的方式求最小生成树结果WA,后来看了下别人的题解,二分出一个最大值delta使得A公司的边加上这个值后再求MST时A公司的边有大于等于k条,然后答案就是cost of MST - k * delta。思想就是用一个delta去逼近答案。当delta越大的时候A公司的边就越少,反之越多。所以二分delta可以找到使得A公司刚好取K条边的要求。# 阅读全文
posted @ 2013-07-28 21:11 一生挚爱 阅读(265) 评论(0) 推荐(0)
摘要:题意: 莱克尔和她的朋友到公园玩,公园很大也很漂亮。公园包含n个景点通过n-1条边相连。克莱尔太累了,所以不能去参观所有点景点。经过深思熟虑,她决定只访问其中的k个景点。她拿出地图发现所有景点的入口都很特殊。所以她想选择一个入口,并找到一条最短的路来参观k个景点。我们假设景点之间的距离为1。解题思路:因为地图形状为树形,所以求树的最大直径。当k小于等于直径的时候输出k-1,当k大于直径的时候,因为访问了某一个景需要返回直径所在的路径上,所以当k大于冷的时候结果为len-(k-len-1)*2。#include #include #include #include #include using 阅读全文
posted @ 2013-07-28 17:55 一生挚爱 阅读(519) 评论(0) 推荐(0)
摘要:#pragma comment(linker,"/STACK:102400000,102400000")#include #include #include #include #include #include using namespace std;const int maxn = 200100;const int maxm = 2000100;struct node{ int v,next;}edge[maxm];struct Bridge{ int u,v;}bridge[maxm];int head[maxn],vis[maxm],fa[maxn],dfn[maxn 阅读全文
posted @ 2013-07-28 15:46 一生挚爱 阅读(297) 评论(0) 推荐(0)
摘要:题意: 平面上,一个圆,圆的边上按顺时针放着n个点。现在要连m条边,比如a,b,那么a到b可以从圆的内部连接,也可以从圆的外部连接。给你的信息中,每个点最多只会连接的一条边。问能不能连接这m条边,使这些边都不相交。解题报告:题意可能刚开始不是很好理解,比如1 5连边,2,6连边,由于点是顺序排列的,一画图就可以发现,这两条边必须一个从圆外面连,一个从内部连,否则就会相交。如果再加入3 7这条边,那么就必须相交了。这样,就可以转化成标准的2-sta问题:1:每个边看成2个点:分别表示在内部连接和在外部连接,只能选择一个。计作点i和点i'2:如果两条边i和j必须一个画在内部,一个画在外部( 阅读全文
posted @ 2013-07-27 11:00 一生挚爱 阅读(217) 评论(0) 推荐(0)
摘要:第一次按常规的方法求,将所有的查询的u,v,和最近公共祖先都保存起来,然后用tarjan+并查集求最近公共祖先。因为询问的次数过多,所以在保存查询的时候总是MLE,后来参考了一下别人的代码,才突然觉悟,可以先将u,v,和其最近公共祖先保存到数组,然后再求结果,为什么不能直接保存其结果了。如果只保存结果的话,保存查询操作就可以节约1/3的内存,所以基本可以过了。代码如下:方法一:#include #include #include #include #include using namespace std;const int maxn = 10100;vector >tree[maxn], 阅读全文
posted @ 2013-07-26 21:31 一生挚爱 阅读(170) 评论(0) 推荐(0)
摘要:记忆化搜索题目大意:老鼠出来后停在哪个格子就将那个格子里面的食物吃掉。每次出来都只能吃一方格的食物,每次出来最多跳过k个有食物的格子去吃另外那个格子里面的食物。思路:本题用记忆化搜索。其实就是记录在一个点上在之前搜索过程中的最大值,如果后来搜到了这没有大于这个值就停止搜索, 如果大于这更新这个最大值并继续搜索。题目源码如下:#include #include #include #include using namespace std;const int maxn = 110;int map[maxn][maxn],mark[maxn][maxn];int up[] = {0,0,1,-1};i 阅读全文
posted @ 2013-07-22 15:06 一生挚爱 阅读(143) 评论(0) 推荐(0)