自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 [SPOJ7258]SUBLEX - Lexicographical Substring Search(后缀自动机)

题目描述传送门题解明明是sa的题嘛,可是为了练习sam用sam来写 sam从根到每一个点的路径都构成了一个子串,并且这些子串都是本质互不相同的 所以我们可以用拓扑序或者dfs统计一遍当前节点再往后走会有多少个不同的子串 然后询问的时候暴力枚举每一个点的每一个儿子然后找第k个就行了代码#include<iostream>#include<cstring>#include<cstdio>us

2016-12-30 10:04:14 645

原创 [SPOJ8222]NSUBSTR - Substrings(后缀自动机)

题目描述传送门 题意:定义f(i)为长度为i的子串的最多出现次数(可重复),求f(1…n)题解很显然f(1..n)不升,那么可以用f(i)=max{f(i),f(i+1)} right集合表示当前状态在哪里出现过,其实就是求right集合的大小 主链上的所有的点right集合初始为1(因为它代表了原串的一个前缀) 如果两个点的right集合有交集,那么一定一个是另一个的真子集 所以在par

2016-12-30 08:33:31 855

原创 [SPOJ1812]LCS2 - Longest Common Substring II(后缀自动机)

题目描述传送门 题意:给出若干串,求最长公共子串。题解首先对于第一个串构建sam 对于某一个状态s,如果除第一个串之外的串匹配到此所得的最长长度是a1,a2,a3...an−1a_1,a_2,a_3...a_{n-1},那么这个状态的最长公共子串应为Min{a1,a2,a3...an−1,Max(s)}Min\{a_1,a_2,a_3...a_{n-1},Max(s)\} 同样,如果当前点被匹

2016-12-29 21:30:59 846

原创 [SPOJ1811]LCS - Longest Common Substring(后缀自动机)

题目描述传送门 题意:给出两个串,求最长公共子序列。题解后缀自动机第一题。 首先对第一个串建立sam,然后让第二个串在sam上暴力匹配,匹配不到就蹦到它的pre指针。匹配上的子串最长长度就是最长公共子序列。代码#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 500005cha

2016-12-29 20:53:42 850

原创 后缀数组 学习笔记

后缀数组定义搞懂定义是学习后缀数组的关键。 子串:字符串 S 的子串 r[i..j] ,i ≤ j ,表示 r 串中从 i 到 j 这一段,就是顺次排列r[i],r[i+1],…,r[j]形成的字符串。 后缀:后缀是指从某个位置 i 开始到整个串末尾结束的一个特殊子串。字符串 r 的从 第 i 个字 符 开 始 的 后 缀 表 示 为 Suffix(i) ,也就是Suffix(i)=r[i..l

2016-12-29 07:09:27 1223 4

原创 [BZOJ4516][Sdoi2016]生成魔咒(后缀数组+链表||后缀自动机)

题目描述传送门题解题意实际上是求对于每一个前缀本质不同的子串个数 那么可以转化为对于每一个前缀只求包含最后一个点的和前面不重复的子串个数,然后将答案累加 把串反过来建后缀数组 然后实际上就是对于每一个后缀求与其它后缀不重复的前缀个数,也即是后缀长度减去height值 但是需要注意的一点是要排除在其后面的后缀的干扰 那么可以倒序求解,求解之后将这个后缀删除,height不升,可以用链表维护一

2016-12-28 18:38:57 949

原创 [BZOJ3230]相似子串(后缀数组+二分+st表)

题目描述传送门题解题目实际上是要求最长公共前缀和后缀的长度的平方和。个人认为题目描述中a和b应该取min 把这个串正反都求一下sa和height 由于是本质不同的子串,所以每一个后缀的贡献应该是当前串刨去它和前一个的lcp的剩下的前缀 可以求出贡献的前缀和,显然满足单调性 对于每组询问,二分找出这两个子串在rank里的位置,然后用rmq求区间最小值 再找出这两个子串的结尾的位置,在反串那边

2016-12-28 11:30:35 854 3

原创 [BZOJ3238][Ahoi2013]差异(后缀数组+单调栈||后缀自动机+树形dp)

题目描述传送门题解这道题实际上还是非常有趣的。 首先根据题目的描述答案应该为所有后缀的组合长度再减去两两的lcp 首先算出来总和 求出sa和height,用两次单调栈可以求出来以某一个点的height为最小值的最长区间 可以发现以这个点为分界点,区间的左右两边两两组合最小值一定是当前点的height,也就是lcp的长度 然后再计算答案就可以了代码#include<iostream>#in

2016-12-28 10:00:50 808

原创 [BZOJ2251][2010Beijing Wc]外星联络(后缀数组)

题目描述传送门题解首先求出来sa和height 然后其实就是暴力计算一下每一个后缀向后延伸多远。 注意要去掉重复的,也就是说要从每一个最长的那个后缀开始,并且对于每一个后缀,要从大到小合并。 时间复杂度O(nlogn+n2)O(nlogn+n^2)代码#include<iostream>#include<cstring>#include<cstdio>using namespace st

2016-12-28 09:55:24 767

原创 [POJ1226]Substrings(后缀数组+二分)

题目描述传送门题解先将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组。然后二分答案,再将后缀分组。判断的时候,要看是否有一组后缀在每个原来的字符串中至少出现两次,并且在每个原来的字符串中,后缀的起始位置的最大值与最小值之差是否不小于当前答案(判断能否做到不重叠)。代码#include<iostream>#include<cstring>#include<cstd

2016-12-27 23:02:21 862

原创 [SPOJ220]PHRASES - Relevant Phrases of Annihilation(后缀数组+二分)

题目描述传送门 题意:给定 n 个字符串,求在每个字符串中至少出现两次且不重叠的最长子串。题解先将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组。然后二分答案,再将后缀分组。判断的时候,要看是否有一组后缀在每个原来的字符串中至少出现两次,并且在每个原来的字符串中,后缀的起始位置的最大值与最小值之差是否不小于当前答案(判断能否做到不重叠)。代码#include<al

2016-12-27 22:59:26 678

原创 [POJ3294]Life Forms(后缀数组+二分)

题目描述传送门题解将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求sa和height。然后二分答案,将后缀分成若干组,每一组的height都不小于mid,判断每组后缀是否出现在不小于 k=n/2+1 个的原串中。注意: ①n=1的时候要特判 ②每一个height都不能超过它本身表示的字符串的长度代码#include<iostream>#include<cstring>

2016-12-27 20:12:05 759

原创 [BZOJ3277]串(后缀数组+二分+st表)

题目描述传送门题解orz hxy sam随便艹 不过我感觉这道题用sa的做法非常厉害吖 由于每一个子串一定是某一个后缀的前缀,所以可以对于每一个后缀求其对答案能贡献多少个子串,也就是这个后缀有多少个满足题意的前缀。同时可以发现,对于同一个后缀SiS_i,如果Si,jS_{i,j}满足题意那么Si,i...Si,jS_{i,i}...S_{i,j}都满足题意,也就是说这个贡献的值也是满足单调性的,

2016-12-27 18:59:14 1162

原创 [POJ3415]Common Substrings(后缀数组+单调栈)

题目描述传送门 题意:给定两个字符串 A 和 B ,求长度不小于 k 的公共子串的个数(可以相同)。题解首先把一个串接在另一个串的后面,中间放一个没出现过的字符。 由于每一个子串都是某一个后缀的前缀,求出sa和height了之后,我们可以将height分组,组内都是height>=k的后缀。可以知道长度不小于k的公共子串是两个后缀的前缀,并且它们一定在同一组内。 那么对于每一组,从前往后扫,假

2016-12-26 21:20:13 1839

原创 [POJ3693]Maximum repetition substring(后缀数组+st)

题目描述传送门 题意:给定一个字符串,求重复次数最多的连续重复子串。输出满足题意的子串,如果有多个,输出字典序最小的。题解先枚举长度 L ,然后求长度为 L 的子串最多能连续出现几次。首先连续出现 1 次是肯定可以的,所以这里只考虑至少 2 次的情况。假设在原字符串中连续出现 2 次,记这个子字符串为 S ,那么 S 肯定包括了字符 r[0], r[L], r[L*2], r[L*3], …… 中

2016-12-26 11:36:16 529

原创 [SPOJ687]REPEATS - Repeats(后缀数组+st)

题目描述传送门 题意:给定一个字符串,求重复次数最多的连续重复子串。题解先枚举长度 L ,然后求长度为 L 的子串最多能连续出现几次。首先连续出现 1 次是肯定可以的,所以这里只考虑至少 2 次的情况。假设在原字符串中连续出现 2 次,记这个子字符串为 S ,那么 S 肯定包括了字符 r[0], r[L], r[L*2], r[L*3], …… 中的某相邻的两个。所以只须看字符 r[L*i] 和

2016-12-26 11:29:14 654

原创 [SPOJ705]DISUBSTR - Distinct Substrings(后缀数组)

题目描述传送门题解每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数。如果所有的后缀按照suffix(sa[1]), suffix(sa[2]),suffix(sa[3]), …… ,suffix(sa[n]) 的顺序计算,不难发现,对于每一次新加进来的后缀suffix(sa[k]), 它将产生 n-sa[k]+1 个新的前缀。但是其中有 height[k] 个是和前面

2016-12-26 11:24:19 658

原创 [POJ1743]Musical Theme(后缀数组||后缀自动机)

题目描述传送门题解用height搞事情。。。 某个子串一定是一个后缀的前缀。 两个后缀的最长公共前缀是在 height 数组上的区间最小值。 先二分答案,把题目变成判定性问题:判断是否存在两个长度为mid的子串是相同的,且不重叠。把排序后的后缀分成若干组,其中每组的后缀之间的 height 值都不小于 k 。有希望成为最长公共前缀不小于 k 的两个后缀一定在同一组。 然后对于每组后缀,只须判断

2016-12-26 11:21:07 1292 2

原创 AC自动机 学习笔记

Q:给出一坨短串,给出一个长串,求有多少个短串在长串中出现了。 A:把短串丢进trie树,建立fail指针,把长串在trie树上匹配,暴力蹦fail即可。每一个点只会被蹦一遍,打标记即可。Q:给出一坨短串,给出一个长串,求每一个短串在长串中出现了多少次。 A:把短串丢进trie树,建立fail指针,把长串在trie树上匹配,能匹配上的点size都+1,然后建立fail树,统计每一个短串end节点

2016-12-25 10:37:45 874

原创 关于 Nim游戏与SG函数 的一点研究

引言在《博弈圣经》中博弈论的定义:我们把动物利用大自然移动的瘾魂,在决策人期待的空间里,形成三维均衡的语文学理论,称为博弈论。 博弈论又被称为对策论(Game Theory)既是现代数学的一个新分支,也是运筹学的一个重要学科。 博弈论主要研究公式化了的激励结构间的相互作用。是研究具有斗争或竞争性质现象的数学理论和方法。 博弈论考虑游戏中的个体的预测行为和实际行为,并研究它们的优化策略。生物学家使

2016-12-25 10:36:57 2850

原创 [BZOJ3881][Coci2015]Divljak(AC自动机+dfs序+lca+bit)

题目描述传送门题解首先把所有的S串都丢到trie树里,建立fail树。 每加进来一个T,把它在AC自动机上暴力匹配,匹配到的每一个点在fail树中到根的路径上出现过的S串end标记的S串都应该+1,也就是说,每一次求出匹配到的每一个点在fail树中到根的路径上出现过的end标记表示的S串,然后取并集,这些S串的答案应该+1. 由于有可能有重复计算,我们需要把所有匹配过的点按照dfs序排序,然后要

2016-12-25 10:35:27 667

原创 [BZOJ2938][Poi2000]病毒(AC自动机+拓扑排序)

题目描述传送门题解如果把给出的所有串建成trie树的话,那么有解的条件就是在匹配不到end节点的情况下无限地匹配下去。 注意不是只有每一个串的结束节点才是end节点,根据fail树的性质,假设y的fail指针指向x,那么如果x有end标记y也一定有end标记,因为x是y的一个后缀。 对于某一个节点如果它没有某一个儿子那么就把它这个儿子表示成它的fail的那个儿子。这样的话就形成了一个trie图。

2016-12-24 23:18:10 938

原创 [BZOJ1212][HNOI2004]L语言(AC自动机+dp)

题目描述传送门题解这道题我开始就想到了暴力,但是算一算时间复杂度是O(20∗10∗1M)≈2∗108O(20*10*1M)\approx 2*10^8这很显然不科学啊。。 但是上网查了一下题解发现大家好像都是用的很暴力的方法,并且还有人说20*10*1M轻松过我也不知道是为什么1M不应该是102421024^2嘛?dp的思路非常好想,就是f(i)表示前i个是不是合法的串,可以知道如果位置i减去任何

2016-12-24 23:06:59 796

原创 [BZOJ3940][Usaco2015 Feb]Censoring(AC自动机+栈)

题目描述传送门题解和BZOJ3942是差不多的。 搞一个栈,然后边匹配边压栈,匹配不了就跳到失配,匹配成功就暴力弹栈。 需要注意的一点是,弹栈之后要将当前匹配的节点恢复到栈顶元素的位置,然后从下一个元素开始继续匹配。 单个串kmp就可以完成,多个串改成AC自动机来做。代码#include<iostream>#include<cstring>#include<cstdio>#include

2016-12-24 23:00:11 1227

原创 [HDU3065]病毒持续侵袭中(AC自动机)

题目描述传送门 注意:题目有多组数据。题解之前写过这道题,但是感觉复杂度应该是O(S∗len)O(S*len)的,也就是5∗1075*10^7 换了一个更科学的做法。就是每一次匹配都把它的权值+1,然后最后再fail树上统计子树和。 用到的性质就是fail树上的节点到根路径上的点都是这个点表示的字符串的前缀的后缀。 这样的话时间复杂度应该是O(S+N∗len)≈2.05∗106O(S+N*l

2016-12-23 23:19:00 667

原创 [BZOJ3576][Hnoi2014]江南乐(博弈Multi-SG游戏+数学相关)

题目描述传送门题解可以发现暴力就是一个裸的Multi-SG游戏。 用SG函数暴力的话,可以枚举m,然后再根据分成m份之后两个x/i和x/i+1的个数奇偶讨论一下就可以了。 但是这样的话时间是O(n2)O(n^2)的。 考虑怎么优化。发现x/i只有n√\sqrt n种取值,并且x/i和x/i+1个数的奇偶随i而变化。然后就可以用以前的一种数学方法用⌊x⌊xi⌋⌋\lfloor{{x\over {

2016-12-23 13:45:10 974

原创 [HDU2509]Be the Winner(博弈Anti-SG+Multi-SG游戏)

题目描述传送门题解就是一个Anti-SG和Multi-SG游戏的结合。 求出SG函数了之后用结论就可以了。 不过这道题是可以证明堆的大小为i的堆sg=i 用归纳法,首先sg(0)=0显然。 假设对于0-n-1sg(i)=i都成立,证明sg(n)=n 可以看出求n的sg函数实际上就是将所有相加小于n的数两两异或起来然后取一个最小的没有用过的 那么我们就需要证明0-n-1两两异或起来取遍0-

2016-12-23 08:56:40 544

原创 [BZOJ1299] [LLH邀请赛]巧克力棒(博弈Nim游戏)

题目描述传送门题解首先先手从中选出一个极长的子序列使它们的异或和=0,这就相当于是建立一个一个先手必败的Nim游戏。 然后后手如果再取出一个子序列就相当于是建立一个先手必胜的Nim游戏,这时候先手只需要将其变成必败的,让后手一直面对这一堆必败的Nim游戏就可以了。如果先手不能选出一个子序列使它们的异或和=0,那么他建立的Nim游戏就是先手必胜的。即使后手也必须建立先手必胜的Nim游戏,但是由于先手

2016-12-23 08:15:17 755

原创 [BZOJ2463] [中山市选2009]谁能赢呢?(博弈)

题目描述传送门题解还想用SG打表来着… 实际上,如果n为奇数的话Bob胜,否则Alice胜。 其实很好理解,因为如果n为奇数,走满所有格须移动偶数次,n为偶数的话奇数次,然后少到一格少移动两次,奇偶性不改变,所以即可判断胜负。代码#include<iostream>#include<cstring>#include<cstdio>using namespace std;int n;in

2016-12-22 23:33:41 528

原创 [BZOJ1982][Spoj 2021]Moving Pebbles(博弈)

题目描述传送门题解同PKU New Stone Game代码#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 100005int n;int a[N];int main(){ while (~scanf("%d",&n))

2016-12-22 23:30:45 760

原创 [BZOJ1188][HNOI2007]分裂游戏(博弈SG函数)

题目描述传送门题解本来想写一个二维的SG,一维是位置一维是个数,但是发现做不了多少就炸了。 后来发现只有石子个数是奇数是有意义的,因为偶数的都可以模仿操作对吧。 那么这样的话就相当于是一坨1来做,然后每一次可以将一个游戏拆成两个游戏,这不就是典型的Multi-SG吗。 用SG函数记忆化搜索就可以解决了。 最后找方案的话暴力就可以,实际上还可以简化一下,ans^sg(i)^sg(j)^sg(k

2016-12-22 23:29:30 888

原创 [BZOJ2940][Poi2000]条纹(博弈Multi-SG游戏)

题目描述传送门题解博弈论中Multi-SG游戏裸题。代码#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 1005int a,b,c,T,n,ans;int sg[N];int get_sg(int x){ if (sg[x]!=-1) return sg[x];

2016-12-22 19:26:52 905

原创 [POJ3710]Christmas Game(博弈树的删边游戏)

题目描述传送门 题意:有 N个局部联通的图。 Harry 和 Sally轮流从图中删边,删去一条边后,不与根节点相连的部分将被移走。Sally为先手。图是通过从基础树中加一些边得到的。所有形成的环保证不共用边,且只与基础树有一个公共点。 谁无法移动谁输。 题解博弈论中典型的树的删边游戏,以及对环的处理方法。代码#include<iostream>#include<cstring>#

2016-12-22 18:54:16 1483

原创 [HDU3595]GG and MM(博弈Every-SG游戏)

题目描述传送门 题意:一共有n个游戏,每一个游戏有两堆石子,一次移动可以从大的那堆石子里拿小的那堆石子的整数倍的石子。只要是可以操作的游戏都要进行操作,不能进行操作的人负。题解定义Every-SG游戏:对于还没有结束的单一游戏,游戏者必须对该游戏进行一步决策;Every-SG游戏的其他规则与普通 SG游戏相同在通过拓扑关系计算某一个状态点的SG函数时(事实上,我们只需要计算该状态点的SG值是

2016-12-22 18:40:19 690

原创 [POJ3537]Crosses and Crosses(博弈Multi-SG游戏)

题目描述传送门 一个一行n列的棋盘,两人轮流在上面下棋子,连成3个棋子的人获胜。问是否有必胜策略。题解可以发现如果在点i已经有了棋子,那么就不能在i-2,i-1,i+1,i+2这几个地方下棋子,否则就会让对方赢。 那么问题可以转化为在如果在点i已经有了棋子,那么就不能在i-2,i-1,i+1,i+2这几个地方下棋子,不能下棋子的人负。 如果长度为x的棋盘上点i处下了棋子的话,实际上就是将这个游

2016-12-21 20:07:10 804

原创 [BZOJ1022][SHOI2008]小约翰的游戏John(博弈Anti-Nim游戏)

题目描述传送门题解Anti-Nim游戏: 先手必胜当且仅当每一堆的石子个数都为1且异或值=0存在某一堆的石子个数>1且异或值≠\neq0代码#include<iostream>#include<cstring>#include<cstdio>using namespace std;int T,n,ans;int a[50];int main(){ scanf("%d",&

2016-12-21 18:26:42 746

原创 [POJ2484]A Funny Game(博弈)

题目描述传送门 题意:一圈硬币,每次可以拿走一个或者相邻的两个,不能操作的人负。问是否有必胜策略。 注意:硬币拿走了之后位置为空,即左右两边的硬币不相邻。题解看起来吓人实际上就是一道水题… 如果有1个或者2个都是先手必胜对吧 但是如果>=3个了之后,无论先手怎样取,后手都可以构造对称的局面,然后模仿先手的动作,最终保证必胜。代码#include<iostream>#include<cstr

2016-12-21 18:22:27 559

原创 [POJ2505]A multiplication game(博弈)

题目描述传送门 题意:起始数为1,每次可以将这个数乘2或乘9,首先得到>=n的数的人获胜。问是否有必胜策略。题解这道题我用了一个非常奇怪的方法。 当n<=18的时候随便讨论一下就行了。来看n>18的情况。 首先我们将n分解为18k∗x18^k*x的形式(x有可能为实数)。 1、当x=1的时候,先手必败。因为无论先手选择2还是9,后手都可以选择另一个数将其凑成18. 2、当x>9的时候,先手

2016-12-21 17:45:07 664

原创 [POJ2425]A Chess Game(博弈SG函数)

题目描述传送门 题意:给出一个有向无环图,某些节点上可能有棋子。每一次可以移动一颗棋子到它的后继节点上,不能操作的人负。问是否有必胜策略。题解SG函数裸题。 注意需要用到记忆化搜索,因为后继状态可能被搜索很多次。代码#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 1005in

2016-12-21 17:17:08 760

原创 [POJ1740]A New Stone Game(博弈)

题目描述传送门 题意:有若干堆石子,每一次需要从一堆石子中拿走一些,然后如果愿意的话,再从这堆石子中拿一些分给其它任意堆。不能操作的人负。题解最简单的情况是,如果有两堆数量一样的石子,后手只需要模仿先手的移动,来保持两堆一直相等就可以了,这样先手必败。由此也可以推知,如果石子数量相等的堆都有偶数个的话,同样先手必败。 进一步推理。如果石子堆数为奇数的话,先手只需要把最大的那一堆拿走然后分配使剩下

2016-12-21 17:12:04 1381

空空如也

空空如也

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

TA关注的人

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