随笔分类 - ACM
摘要:经典问题,并查集实现题意:略,几题的分析也略,黑书81页有分析另外网上也能找到很多注意一些特判的情况就不回WA,另外题意描述确实不够准确,稍后更新具体的分析部分1.可能出现两个等式长度不等的情况,直接判为无解2.对于k=0,即没有英文单词只有01的时候只要比较这两个串是否相同即可,相同结果为1,不同为0,其实不需要特判也行,但是我采用了特判3.不同字母可以用相同的01表示,好像a,b,按理说是不同的字母应该有不同的表示,不能一样,但是是允许的,即可以同时为某个01组合4.没用上的英文单词也需要计算在内好像32 2 22ab2ab答案是多少?应该是2^2*2^2=16?,虽然c没有用上,但是也要
阅读全文
摘要:LCA题意:一个无根树,给出主角一开始所在的位置S,然后下面q个操作,操作包括查询和修改操作,对于查询操作就是当前主角的位置到目的点的距离是多少,然后主角去到那里之后就在那里等待,下次查询的时候那里就是新的起点(所以sample中第二次查询为什么是3)。修改是修改第k条边的权值,边的编号就是输入的顺序。这题可能是数据水了还是怎么,对于修改操作虽然有优化的方法,但是用最朴素的直接遍历下去修改也是可行的,不会超时,不过时间就比较糟糕了修改操作其实是修改了一部分子树的dir值,对于查询操作就是普通的LCA这里只能用RMQ了,不能用Tarjan#include <iostream>#inc
阅读全文
摘要:LCA参考Yuan神博客:/*题意:给出一棵节点有值的树,给出Q个询问(a,b),问从a到b的最大盈利(即:先在最小值买入,再在最大值卖出)我有想过用一个新序列w2-w1,w3-w2,,wn-wn-1这样只需用O(n)求得最大子段和即为结果Max-Min了但Q很大,每次都找一个路径会超时用类似Tarjan算法进行处理,但在find()那里要修改一下对每个几点记录4个值up[v]表示从v到目前的根的最大盈利down[v]从目前的根到v的最大盈利Max[v]表示到目前的根的最大值Min[v]表示到目前的根的最小值转移看update!在LCA(u,v)处再来计算,这样那四个值才是正确的值!!*/#i
阅读全文
摘要:LCA题意:先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂。我们知道,这m条边连上后这颗树必将成环,假设新边为(u,v),那么环为u---->LCA(u,v)------->v-------->u,我们给这个环上的边计数1,表示这些边被一个环覆盖了一次。添加了多条新边后,可知树上有些边是会被多次覆盖的,画图很容易发现,但一个树边被覆盖了2次或以上,它就是一条牢固的边,就是说毁掉它再毁掉任何一条新边都好,树都不会断裂,这个结论也是很容易证明的,画图更明显,所以不累述所以这启发了我们,要统计所有
阅读全文
摘要:递推(DP)http://codeforces.com/contest/313/problem/B题意:比较好懂,一个字符串只有.或者#字符,给你一段区间[x,y],其实y>x,让你在这个区间里面统计一个数字,即这个子串,相邻两位,若s[i]=s[i+1]则计数一次,然后输出结果这题一看,其实想到了线段树,因为原串,如果一段连续的.....则看成是一串白色的段,一段连续的#####则看成是一段黑色的段,那么原串可以看成是线段树的总区间被一系列的黑白段覆盖,对于每个查询就在线段树上查询它被什么黑白段覆盖,并且覆盖了多长,不过鉴于比赛时间短,而且好像大材小用的感觉,就没再往线段树上面想,比赛
阅读全文
摘要:LCA题意:询问LCA,不过图不连通,如果两点不连通输出那串英文否则输出两点间的距离,模板题#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define N 10010#define M 10010#define Q 1000010int head[N];struct edge{ int u,v,w,next;}e[2*M];int __head[N];struct ask{ int u,v,lca,next;}ea[2*Q];int dir[N],fa[N
阅读全文
摘要:二维RMQ题意:给一个n*m的矩阵,下面q的询问,每个询问给出一个子矩阵的左上角和右下角的坐标,要你求出这个子矩阵里面的最大元素,然后输出,并且,这个最大元素和子矩阵的四个角上的元素比较,只要能和其中一个元素相等,就输出yes,否则输出no一维RMQ的ST算法,是叫一段2^i长度的序列分成两个2^(i-1)的序列然后计算。二维的RMQ依然使用ST的DP思想,不过对于一个矩形,将其分成完全相等的4个部分,然后求最值,特殊情况是,当一个子矩阵的宽为1,即在宽上不能二分的时候,已经长为1,即长不能二分的时候,其实就是一个一维的RMQ,我是采用了单独处理的方法(我把它归为初始化的一部分),而对于一般情
阅读全文
摘要:连通分量+LCA题意:一个无向图可以有重边,下面q个操作,每次在两个点间连接一条有向边,每次连接后整个无向图还剩下多少桥(注意是要考虑之前连了的边,每次回答是在上一次的基础之上)首先运行一次tarjan,求出桥和缩点,那么远无向图将缩点为一棵树,树边正好是原来的桥。每次连接两点,看看这两点是不是在同一个缩点内,如果是,那么缩点后的树没任何变化,如果两点属于不同的缩点,那么连接起来,然后找这两个缩点的LCA,,因为从点u到LCA再到点v再到点u,将形成环,里面的树边都会变成不是桥。计数的时候注意,有些树边可能之前已经被标记了,这次再经过不能再标记首先按思路写了个代码,跑了2s多,因为显式建树了。
阅读全文
摘要:LCA题意:LCA模板题,输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面的那个字母无视掉,没用的。接着k,下面k个询问lca,输出即可有人说要考虑不连通的情况,我没考虑AC了,另外可能有u,u这样的询问,不过这不影响,照样是写模板,没有特判,一样能过还是Tarjan快一些LCA转RMQ在线算法#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define N 40010#define M 25in
阅读全文
摘要:LCA模板题题意:给一个无根树,有q个询问,每个询问两个点,问两点的距离。求出 lca = LCA(X,Y) , 然后 dir[x] + dir[y] - 2 * dir[lca]dir[u]表示点u到树根的距离下面两份代码都可以通过HDU的C++和G++,都不存在爆栈问题,网上很多人说会爆栈,加了申请系统栈语句,其实不用,而且好想比赛中不允许使用的Tarjan算法跑得更快些,C++ 15ms, G++ 50ms 左右, RMQ大概60ms在线算法:LCA转化为RMQ#include <iostream>#include <cstdio>#include <cst
阅读全文
摘要:LCA题意:给一个无根树,有q个询问,每个询问3个点,问将这3个点连起来,距离最短是多少,LCA的模板题,分别求LCA(X,Y),LCA(X,Z),LCA(Y,Z),和对应的距离,然后3个距离相加再除以2就是这个询问的结果对于一对点,x,y, lca = LCA(x,y) , 那么点x到点y的距离为 dir[x] + dir[y] - 2 * dir[lca] ; 其中dir[u] 表示点u到树根的距离由于是模板题,只给代码,详细的讲解可以在学习笔记里面找《LCA与RMQ》在线算法:LCA转RMQ#include <iostream>#include <cstdio>#
阅读全文
摘要:http://codeforces.com/problemset/problem/289/B水题。。。。。睡觉前水一下题意:给一个矩阵和一个值D,矩阵内每个元素可以多次加减D,目的是让整个矩阵的元素都变得相等,如果做不到输出-1想了一下,觉得好像挺水。。。。。首先,矩阵是多余的,直接一个数组就行了,无非是让数组元素都相等对于两数字A,B,如果它们的差值不是D的倍数,那么无论它们怎么加减都没办法变得一样,只要一对数字不行,整个序列就失败了对于两数字A,B,它们的差值是D的倍数,例如kD,那么他们可以变为相等,要变相等的最小次数就是k,变换方式很多,小的变成大的,大的变成小的,两者都往中间值靠拢,
阅读全文
摘要:状态压缩DP + 优先队列BFS题意:给一个矩阵图,图中只有一个*表示起点,#表示不能到达的点,从A开始有k个大写字母(一定是连续的前k个,但是每个字母的个数不一定),一种大写字母表示一种矿石,一个矿石有两个值ai,bi,表示收集这个矿石需要ai电量,另外,在一个矿石点,可以选择收集或者不收集直接走掉,收集后每走一步,需要多加bi的电量,一开始没有任何矿石,每走一步需要1电量,另外,一开始给你P电量。走的方向是上下左右四个方向。你的任务是在电量用完之前,收集到每种矿石(每种矿石只需要1个),然后回到起点,但是注意一点,在没有收集完之前,不能回到起点,因为一旦回到起点就会瞬间传送回基地。如果有的
阅读全文
摘要:RMQ模板题,用ST算法//DP预处理//dp[i][j] 表示从下标i开始,长度为2^j的最大值//状态转移方程 dp[i][j] = max{ dp[i][j-1] , dp[i+2^(j-1)][j-1] }//也就是一个长度为2^j的区间,二分为两个2^(j-1)的长度//对于查询[a,b]以内的最大值,先求出区间长度LEN = b-a+1//查询结果为 res = max{dp[a][k] , dp[b-2^k+1][k]} , 关键是k,是什么,怎么计算//当满足 2^k >= LEN/2 , 且k最小时,这个k就是我们要的值//k可以用计算公式一步算得 : k = (int
阅读全文
摘要:强连通分量题意:一个n行m列的矩阵图,上面有3种点,可能是数字x(0<=x<=9),表示这里有多少个矿石,#表示不能走到这点,*表示传送点,对应一个目标点,可以瞬间传送到目标点。你从(0,0)左上角处出发,行走的方向只能是向左或者向下,要求你走到某个地方(不一定是右下角),让你得到的矿石最多。一个地方的矿石只能采集一次,下次再去到那个点是没有矿石的。注意几点,传送点可能将你传送到#这种点,那么相当于这个传送点是多余的等于没用,另外在传送点可以选择传送或者不传送继续走。分析:由于传送点的存在,可能使这个有向图构成环,进而可能产生强连通分量,所以先建图,进行一次强连通分量缩点,为什么缩
阅读全文
摘要:强连通分量题意:给一个有向图,对于图中任意两个点u,v,如果从u能到v,或者,v能到u,则这对顶点是可行的,如果图中任意一对顶点都是可行的,可以输出Yes,否则输出No这个的话,就不是裸的强连通分量了。思考一下,对于一个有向图而言,里面的强连通分量肯定满足题目的条件,因为强连通分量内是u可到v,而且,v可到u,所以我们第一步工作就是强连通分量缩点,变为一个DAG。对于这个DAG里面的任意两个点U,V,如果满足题目的条件,那么点U,V里面包含的原图的点也肯定是满足的所以问题转化为怎么判断这个DAG是满足题目条件呢?其实判断很简单,就是看这个DAG里面有多少个点的入度为0,多少个点出度为0如果DA
阅读全文
摘要:双连通分量题意:给一个无向图,要求毁掉两个点,使图变得不连通,图一开始是连通的因为要毁掉两个点,就不是简单的求割点,再看看数据范围,点数为1000,边数为10000,Tarjan的时间复杂度为O(E),如果用枚举法,先枚举要毁掉的第一个点,再用Tarjan进行处理来找割点会不会超时呢?答案是不会,时间为O(v*E),刚好是千万级别,不超做法:先枚举要删除的第1个点,在原图中删除它,看看删除它后整个图的变化 1.整个图变得不连通了(即这个点本身是割点),但是还没完要分类讨论一下 (1).整个图变为两部分,但是两部分刚好都是一个点,那么这两个点再毁掉哪个点都好,图的连通分支数都不会增加...
阅读全文
摘要:双连通分量题意:输入比较恶心,没有说有多少点,点的标号也不一定,只给出了边。一个无向图,但是保证是连通的(所以只要做一次dfs),问那些电脑坏了,会使整个网络断开分成几个部分。其实很直白就是求割点。输出就是,如果整个图为点双连通分量,则输出No SPF nodes , 否则按标号从小到大输出每个割点,并且输出,去掉该点后,整个图会分成几个部分这题算是个模板题,但是WA了,是因为模板有问题,也是自己对双连通分量的理解有问题,改了一下模板过了,发现自己之前想的东西有点复杂,把模板一些细节处搞错了,但是之前做了几道题都是1Y的,这个题目错了,感觉错得很值。对于什么是割点,在这里不说了,百度很多,对照
阅读全文
摘要:双连通分量题意:给一个无向图。如果至少有两个环共用了一些边,那么这些边被认为是“冲突边”。如果一些边不在任何一个环中,这些边被认为是“多余边”。你要找出这个图中有多少“多余边”和“冲突边”然后输出条数。另外这图不一定是连通的1.“多余边”不在任何一个环中,那么多余边一定是桥,所以统计这个无向图中有多少桥即可2.“冲突边”有多少,这个有点费劲,但是不难想到。如果一个环比较特殊,n个点刚好n条边,例如(1,2)(2,3)(1,3)这种环,这个环内,一条“冲突边”都没有,但是如果一个环内的边数大于点数,那么这个环内所有边都是“冲突边”(真可惜,因为有多出来的那些边后,相当于把最外面的大环分割成了内部
阅读全文
摘要:双连通分量边双连通分量+DP (其实不用DP,直接建树+遍历一次就能计算出全部的DP值)题意无向图连通,所以只要从一个点运行一次dfs即可,在运行dfs过程中保存下所有的桥并且计算出所有的边双连通分量。在tarjan之后对原图进行缩点,缩点后就能得到一棵,树边刚好就是全部的桥。缩点后每个大点都有一个权值,权值等于 = 属于该连通分量的每个小点的权值和。因此保存下全部桥是为了方便建树。建树之后对树进行一次遍历(很多人说是DP,其实不算是DP,只是简单的遍历而已)。遍历过程要计算每个节点的dp值,dp[i] = 以点i为节点的子树的所有节点的权值和因此每计算完一个节点的dp值后,就可以看看切断这条
阅读全文