Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suffix_array_and_Trie_added #4

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions gahui_ref/String/Suffix_Array/BOJ_11479
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAX_N 1000011
using namespace std;
//made by chogahui05
class SA
{
private:
int SA[MAX_N];
int lcp[MAX_N];
struct moo
{
int r1,r2,lo,rank;
};
typedef struct moo moo;
vector <moo> v;
public:
void clear()
{
memset(SA,0,sizeof(int)*MAX_N);
memset(lcp,0,sizeof(int)*MAX_N);
v.clear();
}
void get_lcp(char *str)
{
int len = strlen(str);
int loc = -1;
int lo,h=0;
long long ans=0;
vector <int> Rank(MAX_N+1,0);

for(int i=0;i<len;i++)
Rank[SA[i]] = i;

for(int i=0;i<len;i++)
{
if(Rank[i]==0)
continue;
int j = SA[Rank[i]-1];
while(str[i+h] == str[j+h]) h++;
lcp[Rank[i]] = h;
if(h) h--;
}
ans = ans + (long long)(len-SA[0]);
for(int i=1;i<len;i++)
ans = ans + (long long)(len-SA[i]) - (long long)lcp[i];
printf("%lld\n",ans);
}
void build_sa(char *str)
{
int len = strlen(str); moo I;
vector <int> rank(MAX_N+1,0);
vector <int> cnt(54,0);
vector <moo> v;

for(int i=0;i<len;i++)
{
rank[i] = ((str[i]<='Z')?str[i]-'A':str[i]-'a'+26); cnt[rank[i]]++;
}

for(int i=1;i<52;i++)
cnt[i] += cnt[i-1];
for(int i=len-1;i>=0;i--)
SA[--cnt[rank[i]]] = i;

for(int d=1;d<len;d*=2)
{
int r1,r2,mmx=0; v.clear();
for(int i=0;i<cnt.size();i++) cnt[i] = 0;
for(int i=0;i<len;i++)
{
I.r1 = rank[i]+1; I.r2 = ((i+d<len)?rank[i+d]:-1)+1; I.lo = i; v.push_back(I);
mmx = max(I.r1,mmx); mmx = max(I.r2,mmx);
}
sort_v(v,mmx);
//after sorting, calc rank.
for(int i=0;i<v.size();i++)
{
rank[v[i].lo] = v[i].rank; SA[i] = v[i].lo;
}
if(v[v.size()-1].rank==len-1)
break;
}
}
private:
void sort_v(vector <moo> &v,int mmx)
{
vector <moo> temp; temp.resize(v.size());
int co[mmx+1]={0};
for(int i=0;i<v.size();i++) co[v[i].r2]++;
for(int i=1;i<mmx+1;i++) co[i] += co[i-1];
for(int i=v.size()-1;i>=0;i--) temp[--co[v[i].r2]] = v[i];
for(int i=0;i<mmx+1;i++) co[i]=0;
for(int i=0;i<temp.size();i++) co[temp[i].r1]++;
for(int i=1;i<mmx+1;i++) co[i] += co[i-1];
for(int i=temp.size()-1;i>=0;i--) v[--co[temp[i].r1]] = temp[i];

v[0].rank = 0;
for(int i=1;i<v.size();i++)
v[i].rank = v[i-1].rank + (v[i].r1!=v[i-1].r1||v[i].r2!=v[i-1].r2);
}
};
char str[MAX_N];
int main(void)
{
SA sa=SA();
scanf("%s\n",str); sa.clear(); sa.build_sa(str); sa.get_lcp(str);
return 0;
}
119 changes: 119 additions & 0 deletions gahui_ref/String/Suffix_Array/BOJ_9249.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//made by chogahui05
//BOJ 9249
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAX_N 1000011
using namespace std;
class SA
{
private:
int SA[MAX_N];
int lcp[MAX_N];
struct moo
{
int r1,r2,lo,rank;
};
typedef struct moo moo;
vector <moo> v;
public:
void get_lcp(char *str)
{
int len = strlen(str); int h = 0,mmx = 0;
int loc = -1;
int lo;
for(int i=0;i<len;i++)
{
if(str[i]=='$')
loc = i;
}
vector <int> Rank(MAX_N+1,0);
for(int i=0;i<len;i++)
Rank[SA[i]] = i;
for(int i=0;i<len;i++)
{
if(Rank[i]==0)
continue;
int j = SA[Rank[i]-1];
while(str[i+h] == str[j+h]) h++;
lcp[Rank[i]] = h;
if(h) h--;
}

//process
for(int i=1;i<len;i++)
{
if((SA[i]<loc&&SA[i-1]>loc)||(SA[i]>loc&&SA[i-1]<loc))
{
if(mmx<lcp[i])
{
mmx = lcp[i];
lo = SA[i];
}
}
}
printf("%d\n",mmx);
for(int i=lo;i<lo+mmx;i++)
printf("%c",str[i]);
}
void build_sa(char *str)
{
int len = strlen(str); moo I;
vector <int> rank(MAX_N+1,0);
vector <int> cnt(27,0);
vector <moo> v;
for(int i=0;i<len;i++)
{
rank[i] = (str[i]=='$')?26:str[i]-'a'; cnt[rank[i]]++;
}
for(int i=1;i<=26;i++)
cnt[i] += cnt[i-1];
for(int i=len-1;i>=0;i--)
SA[--cnt[rank[i]]] = i;
for(int d=1;d<len;d*=2)
{
int r1,r2,mmx=0; v.clear();
for(int i=0;i<cnt.size();i++) cnt[i] = 0;
for(int i=0;i<len;i++)
{
I.r1 = rank[i]+1; I.r2 = ((i+d<len)?rank[i+d]:-1)+1; I.lo = i; v.push_back(I);
mmx = max(I.r1,mmx); mmx = max(I.r2,mmx);
}
sort_v(v,mmx);
//after sorting, calculate rank
//rank array, SA array fill
for(int i=0;i<v.size();i++)
{
rank[v[i].lo] = v[i].rank; SA[i] = v[i].lo;
}
if(v[v.size()-1].rank==len-1)
break;
}
}
private:
void sort_v(vector <moo> &v,int mmx)
{
vector <moo> temp; temp.resize(v.size());
int co[mmx+1]={0};
for(int i=0;i<v.size();i++) co[v[i].r2]++;
for(int i=1;i<mmx+1;i++) co[i] += co[i-1];
for(int i=v.size()-1;i>=0;i--) temp[--co[v[i].r2]] = v[i];
for(int i=0;i<mmx+1;i++) co[i]=0;
for(int i=0;i<temp.size();i++) co[temp[i].r1]++;
for(int i=1;i<mmx+1;i++) co[i] += co[i-1];
for(int i=temp.size()-1;i>=0;i--) v[--co[temp[i].r1]] = temp[i];

v[0].rank = 0;
for(int i=1;i<v.size();i++)
v[i].rank = v[i-1].rank + (v[i].r1!=v[i-1].r1||v[i].r2!=v[i-1].r2);
}
};
char str[MAX_N];
char pat[MAX_N];
int main(void)
{
SA sa=SA(); scanf("%s\n%s",str,pat);
strcat(str,"$"); strcat(str,pat); sa.build_sa(str); sa.get_lcp(str);
return 0;
}
111 changes: 111 additions & 0 deletions gahui_ref/String/Trie/BOJ_3174.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <vector>
#define M 1337377
using namespace std;
class Trie
{
private :
struct moo
{
int go[26];
int term;
};
typedef struct moo moo;
//arr size must be >= total input_charater number.
moo arr[1<<19];
int sz = 0;
public:
Trie()
{
memset(arr,0,sizeof(moo)*(1<<19)); sz = 0;
}
void add(char *str)
{
int cur = 0;
for(int i=0;str[i];i++)
{
if(arr[cur].go[str[i]-'a']==0)
{
sz++;
arr[cur].go[str[i]-'a'] = sz;
}
cur = arr[cur].go[str[i]-'a'];
}
arr[cur].term++;
}
vector <int> find(char *str)
{
int cur = 0;
vector <int> v; v.clear();
for(int i=0;str[i];i++)
{
if(arr[cur].go[str[i]-'a']==0)
break;
cur = arr[cur].go[str[i]-'a'];
if(arr[cur].term)
v.push_back(i);
}
//if find str in Trie
//check v[v.size()-1] == strlen(str)-1
return v;
}
void del(char *str)
{
int cur = 0;
for(int i=0;str[i];i++)
{
if(arr[cur].go[str[i]-'a']==0)
return;
cur = arr[cur].go[str[i]-'a'];
}
if(arr[cur].term!=0)
arr[cur].term--;
}
};
Trie trie;
char str[300002];
char pat[101];
int dp[300002];
void rev(char *tar);
void build(int lo,int ni);
vector <int> ti;
int main(void)
{
int n; dp[0] = 1; scanf("%s\n%d\n",str+1,&n);
for(int i=0;i<n;i++)
{
scanf("%s\n",pat); rev(pat); trie.add(pat);
}
for(int i=1;str[i];i++)
{
build(i,100);
ti = trie.find(pat);
int ret = 0;
for(int j=0;j<ti.size();j++)
{
ret = ret + dp[i-1-ti[j]]; ret = ret%M;
}
dp[i] = ret;
}
printf("%d\n",dp[strlen(str+1)]);
return 0;
}
void build(int lo,int ni)
{
int p = 0;
memset(pat,0,sizeof(char)*101);
for(int i=lo;i>=max(lo-ni,1);i--)
{
pat[p++] = str[i];
}
}
void rev(char *tar)
{
char temp[101] = {0};
int len = strlen(tar);
for(int i=0;i<len;i++)
temp[len-1-i] = tar[i];
strcpy(tar,temp);
}