spoj 7258 SUBLEX(SAM,名次)】的更多相关文章

[题目链接] http://www.spoj.com/problems/SUBLEX/en/ [题意] 给定一个字符串,询问次序为k的子串. [思路] SAM,名次 建好SAM后求出每个结点根据trans转移向下统计有多少与该结点有相同前缀的子串,每个结点只算一个,因为该结点所代表的字符串集中只可能有一个与上面统计下来的字符串前缀相同,其他的字符串都与该字符串为后缀关系. 设sum(p)为与root->p有相同前缀的字符串,设np=trans(p,x),则有转移式: sum(p)=sigma{…
其实对sam的拓扑排序我似懂非懂但是会用一点了. /** @xigua */ #include <stdio.h> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <cstring> #include <queue> #include <set>…
Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) freopen(s".in","r",stdin) #define maxn 1000000 #define ll long long using namespace std; char str[maxn]; int arr[maxn],pos[maxn],x[maxn]…
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路:构造出sam后,类似splay求前驱的做法,不断的逼近答案.我们知道,sam里从s走到某一节点即为一个子串,所以我们在每个节点下记录一个cnt,表示该节点下,能走到的节点有多少个.那么我们在求第k小的子串时,就往下走,枚举当前节点下的26字母节点,若枚举到的节点的cnt+1>=k那么就往该节点走,…
[题目链接] http://www.spoj.com/problems/SUBLEX/ [题目大意] 给出一个字符串,求其字典序排名第k的子串 [题解] 求出sam上每个节点被经过的次数,然后采用权值线段树上查找第k大数类似的方法, 每次确定查找范围,进入相应的子树,同时输出路径上的点即可. [代码] #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const…
题链: http://www.spoj.com/problems/SUBLEX/题解: 后缀自动机. 首先,因为相同的子串都被存在了自动机的同一个状态里面,所以这就很自然的避免了重复子串的问题. 然后考虑自动机里面的转移trans,发现其构成了一个DAG,且从一个状态出发,DFS下去就可以得到所有的不重复的串; 所以我们按照拓扑序对状态排序,然后DP计算出从每个状态出发可以到达多少个子串. 转移方程:$dp[p]=\sum_{trans(p,*)=q,q!=0}dp[q]+1$ 然后对于每个输入…
http://www.spoj.com/problems/SUBLEX/ 好难啊. 建出后缀自动机,然后在后缀自动机的每个状态上记录通过这个状态能走到的不同子串的数量.该状态能走到的所有状态的f值的和+1就是当前状态的f值. 最后对于询问的k,从root开始走顺便加加减减就可以了. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int in() { int k =…
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! Knowing that, his friend Kinan decided to test his skills so he gave him a string S and asked him Q questions of the form: If all distinct substrings o…
题意:给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 第一道自己做的1A的SAM啦啦啦 很简单,建SAM后跑kth就行了 也需要按val基数排序倒着推出来d[s]状态s的后继子串个数 跑kth的时候判断d[v]>=k的时候就跑到v,并且k应该是--哦,因为一个子串过去了 #include <iostream> #include <cstdio> #include <cstring> #include <al…
题面 第一行给定主串\((len<=90000)\) 第二行给定询问个数\(T<=500\) 随后给出\(T\)行\(T\)个询问,每次询问排名第\(k\)小的串,范围在\(int\)内 相同的子串算一个 Sol \(sam\)中每条从起点出发的路径都对应一个子串 设\(f[i]\)表示从\(i\)出发的路径的条数 \(f[i]=1+\sum_{j\in trans[i]}f[j]\) 最后贪心一遍就好了 # include <bits/stdc++.h> # define IL…