Problems
Started writing conversion in string suffix structs
This commit is contained in:
parent
b125a0be0f
commit
c6d997668a
3 changed files with 117 additions and 8 deletions
|
@ -9,12 +9,20 @@ description: "?"
|
|||
frequency: 1
|
||||
---
|
||||
|
||||
<!--
|
||||
|
||||
TODO:
|
||||
- Add more resources
|
||||
|
||||
-->
|
||||
|
||||
import { Problem } from "../models";
|
||||
|
||||
export const metadata = {
|
||||
problems: {
|
||||
general: [
|
||||
new Problem("CF", "Ciel the Commander", "problemset/problem/321/C", "Easy", false, ["Centroid"], ""),
|
||||
new Problem("Plat", "New Barns", "817", "Normal", true, ["Centroid"], ""),
|
||||
new Problem("CF", "Sherlock's bet to Moriarty", "contest/776/problem/F", "Normal", false, ["Centroid"], ""),
|
||||
new Problem("CF", "Digit Tree", "contest/715/problem/C", "Normal", false, ["Centroid", "NT"], ""),
|
||||
new Problem("CF", "Double Tree", "contest/1140/problem/G", "Normal", false, ["Centroid", "DP"], ""),
|
||||
|
@ -84,9 +92,43 @@ void centroid(int n = 1)
|
|||
|
||||
</CPPSection>
|
||||
|
||||
<JavaSection />
|
||||
<JavaSection>
|
||||
|
||||
<PySection />
|
||||
<!-- Modified from above. I can't guarauntee it compiles and functions as expected -->
|
||||
|
||||
```java
|
||||
boolean[] r = new boolean[MN];//removed
|
||||
int[] s = new int[MN];//subtree size
|
||||
public int dfs(int n, int p)
|
||||
{
|
||||
s[n] = 1;
|
||||
for(int x : a[n])
|
||||
if(x != p && !r[x])
|
||||
s[n] += dfs(x, n);
|
||||
return s[n];
|
||||
}
|
||||
public int get_centroid(int n, int ms, int p)//n = node, ms = size of tree, p = parent
|
||||
{
|
||||
for(int x : a[n])
|
||||
if(x != p && !r[x])
|
||||
if(s[x]*2 > ms)
|
||||
return get_centroid(x, ms, n);
|
||||
return n;
|
||||
}
|
||||
public void centroid(int n)
|
||||
{
|
||||
int C = get_centroid(n, dfs(n, 0), 0);
|
||||
|
||||
//do something
|
||||
|
||||
r[C] = 1;
|
||||
for(int x : a[C])
|
||||
if(!r[x])
|
||||
centroid(x);
|
||||
}
|
||||
```
|
||||
|
||||
</JavaSection>
|
||||
|
||||
</LanguageSection>
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ export const metadata = {
|
|||
new Problem("CSES", "Elevator Rides", "1653", "Normal", false, ["Bitmasks"], ""),
|
||||
new Problem("ojuz", "IZhO Bank", "IZhO14_bank", "Normal", false, ["Bitmasks"], ""),
|
||||
new Problem("YS", "Max Indep Set", "maximum_independent_set", "Normal", false, ["Bitmasks", "Meet in Middle"], ""),
|
||||
new Problem("CF", "Wise Men", "contest/1326/problem/F2", "Very Hard", false, ["Bitmasks", "DP", "SOS"], "Solve the case where for each binary string s, a 1 means that the adjacent men know each other, and the 0 means nothing: they can know each other or not."),
|
||||
],
|
||||
broken: [
|
||||
new Problem("CF", "Guards in the Storehouse", "problemset/problem/845/F", "Normal", false, [], ""),
|
||||
|
@ -44,6 +45,7 @@ You can often use this to solve subtasks.
|
|||
<Resource source="CPH" title="10 (Bit Manipulation), 19.2 (Hamiltonian Paths)"> </Resource>
|
||||
<Resource source="CF" title="DP Over Subsets" url="blog/entry/337"> </Resource>
|
||||
<Resource source="HE" title="DP and Bit Masking" url="https://www.hackerearth.com/practice/algorithms/dynamic-programming/bit-masking/tutorial/"> </Resource>
|
||||
<Resource source="CF" title="SOS Dynamic Programming" url="blog/entry/45223"> Sum over Subsets DP </Resource>
|
||||
</Resources>
|
||||
|
||||
## Problems
|
||||
|
@ -58,4 +60,4 @@ You can often use this to solve subtasks.
|
|||
|
||||
(fill in? more probs?)
|
||||
|
||||
<Problems problems={metadata.problems.broken} />
|
||||
<Problems problems={metadata.problems.broken} />
|
||||
|
|
|
@ -204,7 +204,7 @@ Naively, this would take up $O(N^2)$ memory, but *path compression* enables it t
|
|||
|
||||
<Problems problems={metadata.problems.tree} />
|
||||
|
||||
### Generate Suffix Array
|
||||
### Generate Suffix Array from Suffix Tree
|
||||
|
||||
A suffix array can be generated by the suffix tree by taking the dfs traversal of the suffix tree.
|
||||
|
||||
|
@ -217,12 +217,12 @@ A suffix array can be generated by the suffix tree by taking the dfs traversal o
|
|||
```cpp
|
||||
int N, sa[MN];//length of string, suffix array
|
||||
|
||||
struct edge
|
||||
struct Edge
|
||||
{
|
||||
public:
|
||||
int n, l, r;//node, edge covers s[l..r]
|
||||
explicit operator bool() const {return n!=-1;}
|
||||
} c[MN*2][26];
|
||||
} c[MN*2][26]; // edges of a suffix tree
|
||||
|
||||
void dfs(int n=0, int d=0)
|
||||
{
|
||||
|
@ -239,9 +239,74 @@ void dfs(int n=0, int d=0)
|
|||
```
|
||||
</CPPSection>
|
||||
|
||||
<JavaSection />
|
||||
</LanguageSection>
|
||||
|
||||
<PySection />
|
||||
### Generate Suffix Tree from Suffix Array
|
||||
|
||||
Of course, the above operation can be reversed as well.
|
||||
Each element in the suffix array corresponds to a leaf in the suffix tree.
|
||||
The LCP array stores information about the Lowest Common Ancestor of two adjacent elements in the suffix array.
|
||||
Using these two pieces of information, we can construct the suffix tree from the suffix array in linear time.
|
||||
|
||||
<LanguageSection>
|
||||
|
||||
<CPPSection>
|
||||
|
||||
```cpp
|
||||
//untested
|
||||
int N, sa[MN], lcp[MN];//length of string, suffix array, lcp array: lcp[i] stores longest common prefix of sa[i] and sa[i+1]
|
||||
|
||||
struct Edge
|
||||
{
|
||||
public:
|
||||
int n, l, r; //node, edge covers s[l..r]
|
||||
explicit operator bool() const {return n!=-1;}
|
||||
} c[MN*2][26]; // edges of suffix tree
|
||||
|
||||
void build_tree()
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
</CPPSection>
|
||||
|
||||
</LanguageSection>
|
||||
|
||||
### Generate Suffix Tree from Suffix Automaton
|
||||
|
||||
One interesting thing about Suffix Trees and Suffix Automata is that the link tree of a Suffix Automaton is equivalent to the Suffix Tree of the reversed string.
|
||||
Since Suffix Automata are much easier to create than Suffix Trees, we can use this as an alternate method to build a Suffix Tree, all in linear time too!
|
||||
|
||||
<LanguageSection>
|
||||
|
||||
<CPPSection>
|
||||
|
||||
<!-- https://codeforces.com/edu/course/2/lesson/2/2/practice/contest/269103/submission/85759835 - This submission contains both -->
|
||||
|
||||
```cpp
|
||||
char s[MN]; //string
|
||||
int ord[MN]; // nodes representing prefixes of the string s
|
||||
int u[MN*2]; // whether the node has already been created
|
||||
int l[MN*2]; // link in suffix automaton
|
||||
Edge c[MN*2][27]; // edge of suffix tree (not automaton; structure of automaton is not necessary to build stree)
|
||||
void build_tree()
|
||||
{
|
||||
s[N] = 26; // terminator
|
||||
for(int i=N;i>=0;--i) ord[i]=append(ord[i+1], s[i]);
|
||||
for(int i=0,x,r,l;i<=N;++i)
|
||||
{
|
||||
x=ord[i], r=N+1;
|
||||
for(;x&&!u[x];x=l[x])
|
||||
{
|
||||
l=r-d[x]+d[l[x]];
|
||||
c[l[x]][s[l]]={x, l, r};
|
||||
r=l;
|
||||
u[x]=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</CPPSection>
|
||||
|
||||
</LanguageSection>
|
||||
|
||||
|
|
Reference in a new issue