自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(63)
  • 收藏
  • 关注

原创 CF149E——后缀自动机

题意:给出一个长字符串S和一组询问字符串,对于每个询问需要知道在S中是否存在两个位置不同的子串可以组成该询问字符串。建S的后缀自动机,同时处理出每个状态出现的最左位置和最右的位置。拿每一个询问和S的自动机匹配,记录下询问串中以每个位置为结尾所匹配的长度和匹配自动机中哪个状态。设l为整个询问串所能匹配的长度,那么我们检测这样的结尾i(len - l =#include #include

2013-08-31 17:13:35 783

原创 hdu4507——数位dp

题意:计算给定区间内,不整除7、不含有7、数位之和不整除7的所有数的平方和。思路和普通的数位dp一致,就是求平方和有点恶心。得求出每个状态的三个值:满足该状态的数的个数,这些数的和,这些数的平方和。#include #include #include #include #define lng long longusing namespace std;const int mod

2013-08-13 16:57:14 636

原创 Round #51 Beautiful numbers —— 数位dp

题意:求在给定区间内满足能被自身的所有非零位整除的数的个数。1,2,3,4,5,6,7,8,9的最小公倍数为2520,1到9内任意数字组合的最小公倍数都是2520的因子,那我们在dfs的时候记录目前数模上2520的值pre,同时记录已选数的最小公倍数,到递归结束的时候判断pre模上所有已选数的最小公倍数是否为零。还有一点是:事先把所有的公倍数预处理出来。#include #inclu

2013-08-12 21:21:32 668

原创 hdu3709——数位dp

题意:在给定范围内有多少个数是“平衡数”。平衡数:存在一个“平衡点”,满足每一位到该位的距离(有正负)乘以每位的数字之和等于零。给以看出一个“平衡数”的“平衡点”,一定是唯一的(00000除外)。我们可以枚举每一个平衡点做数位dp。每一位的pre状态即前面所有位的“距离和”,转移的时候新的pre状态为pre + (pos - o) * i,o为平衡点。#include #include

2013-08-11 11:12:31 636

原创 Round #1 B. Spreadsheets

题意:另一种形式的进制转换。import refor _ in range(input()): s = raw_input() p = re.match(r'R(\d+)C(\d+)', s) if p: c = int(p.group(2)) r = p.group(1) while c: r

2013-08-06 10:05:55 609

原创 hdu4416——后缀自动机

题意:问给定的字符串(S)有多少个不同的子串满足不是另外给定的一组字符串(T1~Tn)中任何一个串的子串。把T中的字符串依次拿去和S的自动机匹配。每次匹配到一个状态,更新这个状态所匹配的最大的长度p,那么这个状态所表示的子串中长度大于p的即为我们要找的。在计算答案的时候,我们还要同时更新目前状态的pre状态的p值,所以要按逆拓扑序计算总答案。#include #include #inc

2013-08-05 15:41:13 870

原创 Codeforces Beta Round #93 D. Password——后缀自动机

题意:找到一个字符串的最长的子串满足同时为该串的前缀,中缀和后缀。按逆拓扑序更新每个状态最左出现和最右出现的位置和出现的次数,满足r[s] == len && l[s] - val[s] == 0 && num[s] > 2的所有状态中最长的为我们要的解。#include #include #include #include #define lng long longusing

2013-08-05 14:05:09 776

原创 Codeforces Round #166 (Div. 2) D. Good Substrings——后缀自动机

题意:规定每一个字符的”好坏“,求字符串中坏的字符不超过k个的不同的子串有多少个。数据量是允许n^2的算法过的,一看坏字符的个数是满足区间减法的,就反应过来可以用hash搞了。但是自动机肯定也可以做的。按照拓扑序遍历每个状态,如果当前状态p的pre状态所表示的最长的子串的坏字符个数大于k的话,那这个状态所表示的子串肯定都不满足条件;否则我们就计算出该状态所表示的所有子串中满足条件有多少个,

2013-08-05 12:37:30 708

原创 Codeforces Round #146 (Div. 1) C. Cyclical Quest——后缀自动机

题意:给定一个母串,每次询问一个子串或把子串的前一部分移到末尾形成的串在母串中出现的次数。处理方法都是很常见的。对询问中的每个子串,设长度为len。复制一份放到其末尾位置并把最后一个字符去掉。再拿这个串和母串的自动机匹配,对于询问串的每一个位置,记录该位置往前能匹配的长度,如果长度大于等于len,则通过pre指针找到从这个位置往前len个字符之间的串在自动机中对应的状态。并将答案加上该状态出现

2013-08-04 23:56:51 848

原创 hdu3518——后缀自动机

题意:求一个字符串有多少个不同的子串满足出现了至少两次,且没有重叠。去年作的时候用后缀数组过的,现在写了个后缀自动机。因为一个很脑残的bug(忘了按拓扑序递推)调了两个小时。不过也有收获,在纸上画了10多次建自动机过程之后理解的更清晰了。做法是维护每个状态的最左出现的位置和最右出现的位置(逆拓扑序递推),如果这两个位置之间能放下某些该状态表示的字符串,这些子串加入我们的解中。#incl

2013-08-03 15:12:11 1353

原创 多校第三场——hdu4631——离线

题意:询问一个序列的某一个子区间中的最大的gcd的值。这题关键一点是把最大的gcd转换为最大出现过多次的约数,这样就可以转化为一个求区间最大值的问题了。我从后往前扫一遍原序列,同时记录每一个约数出现的最靠左的位置。每次处理序列中的一个数时,对这个数所有的约数,找到该约数出现的最靠左的位置,并在树状数组中更新该位置的值。在我们处理序列的第i的元素的时候,对于起始位置在i的询问,我们只要求出树

2013-07-31 15:18:20 572

原创 hdu4455——dp

题意:询问一个序列所有长度为w的连续子序列中不相同数的个数之和。思路居然是dp,关键一点是明确每次往序列增加数的时候这个序列的不相同数的个数只会增加或者不变。那我们可以预处理出每个数左边最进且与其相同的数的位置。然后一边递推算出所有的答案。#include #include #include #define lng long longusing namespace std;co

2013-07-31 10:47:21 724

原创 poj1741——树上的分治,树dp

题意:求树上所有满足路径长度小于等于k的两点的对数。思路还是很好理解的,对每一棵子树,以重心为根节点统计在不同子树且相互距离小于等于k的对数。就是实现的细节处理很多,主要都是递归处理的比较多。#include #include #include #include #include #include using namespace std;const int maxn = 5

2013-07-29 22:51:18 596

原创 多校第一场——hdu4604——dp

题意:一次从一个序列里取出一个数放进另一个双端队列里,并且可以随时从这个队列的头和尾弹出元素,同时保证队列里的元素非减。问该队列的长度最大是多少。计算出以每个位置开始的最长非增子序列和非减子序列的长度,减去重复的元素,取最大值。#include #include #include #include #include #include using namespace std;

2013-07-29 11:49:31 498

原创 hdu4267——树状数组

题意:经典的区间更新,单点查询。但是在更新的时候,是更新满足(i - a) % k == 0的点。a为区间左端点。按同余类建55个树状数组,更新的时候落实的具体某一个树状数组上,查询的时候,按i模1~10所得的值去查询对应的树状数组。#include #include #include #include using namespace std;const int maxn =

2013-07-28 16:26:36 588

原创 多校第二场——hdu4618——字符串hash,二分

题意:求一个矩阵的最大回文子矩阵。分奇偶,二分长度,hash判回文。#include #include #include #include using namespace std;typedef unsigned long long lng;const int maxn = 500;const int x = 100000007;int num[maxn][maxn];

2013-07-28 10:26:14 745

原创 hdu3848——树形dp

题意:求一棵树上任意两个叶子节点之间最短的路径。对于那条我们要求的目标路径上的每一个节点,容易看出其到两个叶子节点的路径长度为其到所有叶子节点的最短的和次短的。如果我们在dfs的过程中,对于该路径中第一个到底的节点,我们计算出这个节点到所有的叶子节点最短和次短路径长度就是我们要求的解。我们在dfs的过程记录该节点到所有的叶子节点的最短和次短路径的长度。#include #include

2013-07-25 23:20:48 536

原创 多校第一场——hdu4609——傅里叶变换

题意:随机从N个数中取3个数构成三角形的概率是多少。注意到每个数的范围是1到10^5,可以借鉴生成函数的思想,把任意两个数的和看作多项式的系数用多项式乘法乘出来。可是一般的乘法的时间很作急,就要用到傅里叶变换了。#include #include #include #include #include using namespace std;typedef long long l

2013-07-24 23:07:18 818

原创 多校第一场——hdu4605——离线

题意:给出一棵二叉树,每个节点都有对应的权值。游戏规则是:从根节点开始向下“滚”一个权值为x的物体,到达一个节点的时候:如果x=w[i],即权值相等。则该物体停止移动。如果x如果x>w[i],进入左儿子的概率是1/8,进入右儿子的概率是7/8。询问是:一个权值为x的物体,能够到达u节点的概率是多少?每个节点到根节点的路径都是唯一确定的,我们可以在一遍dfs中,处理掉所有的询问。

2013-07-23 21:28:23 834

原创 hdu4336——数论

题意:求满足以下条件的n有多少个:方法居然是枚举。。。用到一个降幂公式:当n大于p的欧拉函数的值的时候,显然n!%phi(p) == 0,即只需要求:n ^(phi(p)),所以以后的值是循环的:#include #include #include #define lng unsigned long longusing namespace std;

2013-07-23 18:56:49 579

原创 hdu4052——线段树,矩形并

题意:在一个给定大小的平面上给出一些不相交的矩形,在这个平面放一个长度为M的线段且不与任何一个矩形相交,有多少种方法。不失一般性的,可以先求横着放线段的情况。如果枚举放线段的起点的话,那么每个矩形前方m-1长度与自己等宽的区域也是不能放置起点的,那么除去所有不能放置起点的区域,其余区域的面积就是横着放线段的方案数。竖着放同理。求面积,上模板,线段树求矩形并的面积。#include #

2013-07-22 15:34:17 592

原创 hdu4433——dp

去年天津regional的题,就因为这题打铁的。做了一年,惭愧啊。给出两个由数字组成的串,问最少通过几次操作能使第一个变成第二个。操作为将连续的1-3长度的子串的每一位数字同时加一或减一。首先,最短路的话,状态数太多。那么dp的时候,最重要的就是要考虑后效性的问题。可以把后效性枚举出来,反正就两位。dp[i][a][b]表示是前i位和第二个字符串一样,同时第i+1和i+2个字符为a和b

2013-07-18 11:55:34 593

原创 LA3211——2-sat

题意:n架飞机要着陆,每架飞机只有两个时间点可供选择(two-sat有木有啊),安排一个顺序,使得所有飞机的着陆时间当中间隔的最小值最大。这题书上说:“最小值最大”的典型处理方法是二分查找最终答案。我的理解是:如果一个问题满足这个性质:如果一个解满足条件的约束的话,所有比这个解小的解也一定满足。那么我们就可一个二分枚举可能的答案。至于判断一个解是否可行,用2-sat判断。#include

2013-07-09 19:34:55 625

原创 Uva11324——最大团

经典问题,没什么好说的。#include #include #include #include #include #include using namespace std;const int maxn = 1000 + 10;vector g[maxn], g1[maxn];int n, m;int pre[maxn], lowlink[maxn], sccno[maxn

2013-07-09 16:33:26 646

原创 hdu2825——ac自动机,DP

题意:求长度为n,至少包含了给定字符串k个的字符串有多少种。还是多段图递推的思想,不过这一次是在ac自动机上,用10个二进制位表示已经出现的字符串。#include #include #include #include using namespace std;const int maxn = 1000 + 10;const int mod = 20090717;int n,

2013-05-27 17:00:34 476

原创 poj1185——状态压缩DP

一行的状态不仅仅与上一行有关系,而且与上一行的上一行的有关系。那就同时记录最近2行的状态进行DP吧。。。#include #include #include #include #include using namespace std;const int maxn = 1 << 10;int dp[110][200][200];int map[110], m, n;vec

2013-05-19 18:35:06 506

原创 codeforces Round #92 D——后缀自动机

题意:求出一个字符串的所有不同子串出现的次数ni,求所有 ni * (ni + 1) / 2 的和。对这个串建后缀自动机,拓扑排序之后通过pre指针更新出所有的状态所代表的子串在字符串中出现的次数。而每个状态所表示的不同子串的个数为val[s] - val[pre[s]]。#include #include #include #include #define lng long lo

2013-05-05 18:47:59 643

原创 zoj3687——容斥

题意:1到N的数组成一个排列,有些数不能放到指定的位置上,问这种排列有多少种。枚举反面,用容斥原理求出所有的不符合条件的序列,即求出所有的序列,其中之至少有一个数放到了条件中所指定的不能放的位置。#include #include #include #define lng long longusing namespace std;const int mod = 55566677

2013-05-04 20:29:03 576

原创 hdu4427——dp

题意:求满足要求的给定长度有序序列的个数:该序列内的所有数之和为n,最小公倍数为m。首先明确该序列只能由m的因子构成。接下来就是一个比较平常的思路了:dp[i][j][k]表示长度为i,和为j,最小公倍数为k的序列的个数。开三维数组的话,空间不允许,可以用滚动数组,其实这题状态不难想,主要是要优化:要预处理出1000内任意两个数的最小公倍数,甚至memset都不能乱用,不然就会tle。

2013-04-29 12:44:12 1051 1

原创 hdu4421——2-sat

题意:给出了一个数组通过图示转换规则生成一个矩阵:问题是:给出一个矩阵问是否存在一个数组可以通过图示转换得到。可以把数组a中的每个数的每一个位看作一个顶点,由于给出了b,那我们也就知道了一系列的约束条件。#include #include #include #include #include using namespace std;const int maxn

2013-04-27 12:20:14 1017 2

原创 zoj2745——dp

题意:构造指定长度由0和1组成的字符串,且满足任意连续子串中0的个数与1的个数之差的绝对值不大于指定的数k。输出满足条件的不同字符串的个数。这种涉及到任意子区间的性质的问题,如果每个子区间都考虑是很难处理的。注意到0和1的个数之差是满足区间加减法的,也就是说如果我们知道所有后缀的0和1的个数之差那么任意子串的0和1的个数之差也可以间接得出,而在递推的过程中往字符串的末尾中添加字符的时候,会改变

2013-04-27 10:25:03 689

原创 LA3523——无向图的点双连通分量

题意:求一张图中不属于任何一个奇圈的节点的个数。无向图中,若一个点双连通分量内有一个奇圈,可以看出改连通分量内的所有点都可以包含在一个奇圈内,所以可以用dfs求出图中的所有的点双连通分量,每求出一个连通分量,判断其是否为二分图,若为二分图则该连通分量中没有奇圈,若不是二分图,该连通分量中的所有点都不是要求的点。同时要注意一个点可以同时属于多个点双连通分量。#include #includ

2013-04-24 16:37:39 595

原创 Uva11922——splay

题意:根据指令对排列1,2,3,......,n进行操作:每次把区间[a,b]内的数反转后添加到排列的尾部。输出最终的序列。这个可以算splay的模板题了。#include #include #include #include using namespace std;struct node{ node * ch[2]; int v, s; int fl

2013-04-20 16:16:58 579

原创 hdu3726——treap,并查集

题意:给定一个无向图,每个节点都赋予一个权值,给出三种操作:删除一条边。询问节点x所在连通分量的第k大的权值。修改节点x的权值为k。输出所有询问的平均值。可以想到为每一个连通分量建一颗treap,修改操作很好实现,先删后加就行。但是对于删除操作,如果把一个连通分量分成了两个,那就要先把分出去的全删了,再建一棵treap,时间复杂度和代码复杂度都很操蛋的。我们可以反过来想:先

2013-04-17 20:01:53 968

原创 poj2761——treap,区间第K小值

题意:求区间第K小值,待查询的区间之间不会有某一个包含另一个情况。离线处理,把所有查询按左端点的大小排序,由条件可以得出排序后所有查询的右端点一定也是递增的。那我们就可以按顺序处理这些查询,同时更新treap,而且每个元素最多被插入到treap中一次,最多被删除一次。#include #include #include #include #include using namesp

2013-04-15 16:49:03 1102

原创 poj3481——treap

题意:动态求一个集合的最大值和最小值。treap的模板题。#include #include #include #include #include using namespace std;struct node{ node * ch[2]; int r, v, q; bool operator < (const node & rhs) const {

2013-04-15 11:13:10 639

原创 Uva11992——线段树区间更新

题意:先初始化一个全0矩阵,两种更新操作:某个子矩阵的元素全部增加v,和某个子矩阵的元素全部设为v,一种查询:某个子矩阵的元素和,最大值,最小值。矩阵最多20行,建20棵线段树。然后就是成段更新的基本操作了,需要注意的是set操作比add操作的优先级要高,即在set的时候该区间节点的add域一定设为0,反过来却不需要。#include #include #include #inclu

2013-04-14 16:02:41 616

原创 Round #131 (Div. 1) B. Numbers——dp

题意:给出长度为10的数组,规定了0~9这10个数位至少出现的次数,问对于给定的长度n,符合条件且长度不超过n同时没有前导0的数有多少个。用最原始的思路:组合数学的方法,会发现有太多重复的情况会发生,而且几乎不可能不重复不遗漏的把所有的情况数完。一般这个时候就是动态规划派上用场的时候,既然我们不能一次把所有的数都加进来,但是我们可以一个一个的加:先算出满足9的目标数字的个数,再根据已得的数据算

2013-04-13 21:07:24 517

原创 LA3938——线段树区间合并

题意:给定一个长度为n的序列,每次询问一个区间[a, b],求出该区间内最大连续和的范围。维护线段树节点的5个域:l, r区间的左右端点;x, y最大连续和的范围的左右端点;ln最大前缀和的右端点;rn最大后缀和的左端点。在区间合并的时候,分情况讨论,不详述。查询的时候,如果待查询区间“横跨”了所在区间的中点,分三种情况讨论:最大连续和在左区间,在右区间,以及跨区间中点。对于跨区间中点的情

2013-04-12 22:30:56 683

原创 LA3027——带权值的并查集

题意:并查集操作的加强版,每个集群都有一个根节点,每次合并都是把一个根节点变成另外一个集群的节点的儿子,这样就保证了每个集群都只有一个根节点,查询即询问该节点到所在集群的根节点的距离,初始时每个节点都是一个集群。在原有并查集的基础上,增加一个dist数组记录每个节点到其父节点的距离,在路径压缩的时候更新这个数值。更新的时候,还是利用递归,在执行完find(pre[a])之后pre[pre[a]

2013-04-11 09:29:31 626

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除