Skip to content

Commit

Permalink
Added Tree Class
Browse files Browse the repository at this point in the history
  • Loading branch information
zscoder authored Oct 7, 2016
1 parent 3faf195 commit 94f6758
Showing 1 changed file with 276 additions and 1 deletion.
277 changes: 276 additions & 1 deletion Data Structures Class Template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,11 @@ struct Graph
adj[v].pb(tmp);
}

void reset()
{
adj.clear();
}

vi dist;
vi par;

Expand Down Expand Up @@ -1256,14 +1261,284 @@ struct Graph
//End Graph

//Tree
struct Tree
{
struct data
{
ll w;
};

struct node
{
int p; //parent
ll w; //modify for different problems
};

struct edge
{
int v; data dat;
};

vector<vector<edge> > adj;
int n;

Tree(int _n)
{
adj.resize(_n);
n = _n;
}

vi level;
vi depth;
vi h;
vi euler;
vi firstocc;
vector<vi> rmqtable;
vi subsize;
vi start; vi en;
vector<vector<node> > st;

void addedge(int u, int v)
{
edge tmp; tmp.v = v;
adj[u].pb(tmp);
tmp.v = u;
adj[v].pb(tmp);
}

void reset(int _n)
{
adj.clear();
level.clear();
depth.clear();
euler.clear();
rmqtable.clear();
subsize.clear();
start.clear();
en.clear();
st.clear();
firstocc.clear();
adj.resize(_n);
n = _n;
}

void dfssub(int u, int p)
{
subsize[u] = 1;
for(int i = 0; i < adj[u].size(); i++)
{
int v = adj[u][i].v;
if(v == p) continue;
dfssub(v, u);
subsize[v] += subsize[u];
}
}

void calcsub()
{
subsize.resize(n);
dfssub(0, -1);
}

int timer;

void dfsstartend(int u, int p)
{
start[u] = ++timer;
if(p == -1) h[u] = 0;
else h[u] = h[p] + 1;
for(int i = 0; i < adj[u].size(); i++)
{
int v = adj[u][i].v;
dfsstartend(v, u);
}
en[u] = ++timer;
}

void calcstartend()
{
timer = 0;
start.resize(n); en.resize(n); h.resize(n);
dfsstartend(0, -1);
}

int eulercnt;

void dfseuler(int u, int p)
{
euler[eulercnt] = u; eulercnt++;
if(p == -1) {depth[u] = 0;}
else {depth[u] = depth[p] + 1;}
firstocc[u] = eulercnt-1;
for(int i = 0; i < adj[u].size(); i++)
{
int v = adj[u][i].v;
if(v == p) continue ;
dfseuler(v, u);
euler[eulercnt] = u; eulercnt++;
}
}

void calceuler()
{
eulercnt = 0;
level.assign(2*n, 0);
euler.assign(2*n, 0);
depth.assign(n, 0);
firstocc.resize(n);
dfseuler(0, -1);
}

void filllevel()
{
int LG = 0;
while((1<<LG) <= n*2) LG++;
rmqtable.resize(LG);
for(int i = 0; i < LG; i++) rmqtable[i].resize(eulercnt);
for(int i = 0; i < eulercnt; i++)
{
level[i] = depth[euler[i]];
}
level[eulercnt] = 1000000000;
for(int j = 0; j < LG; j++)
{
for(int i = 0; i < eulercnt; i++)
{
rmqtable[i][j] = eulercnt;
if(i + (1<<j) - 1 < eulercnt)
{
if(j == 0)
{
rmqtable[i][j] = i;
}
else
{
if(level[rmqtable[i][j - 1]] < level[rmqtable[i + (1<<(j-1))][j - 1]])
{
rmqtable[i][j] = rmqtable[i][j-1];
}
else
{
rmqtable[i][j] = rmqtable[i + (1<<(j-1))][j - 1];
}
}
}
}
}
}

int rmq(int l, int r)
{
int k = 31 - __builtin_clz(r-l);
//cout << l << ' ' << r << ' ' << rmqtable[l][k] << ' ' << rmqtable[r - (1<<k) + 1][k] << endl;
if(level[rmqtable[l][k]] < level[rmqtable[r - (1<<k) + 1][k]])
{
return rmqtable[l][k];
}
else
{
return rmqtable[r - (1<<k) + 1][k];
}
}

int lcaeuler(int u, int v)
{
if(firstocc[u] > firstocc[v]) swap(u, v);
//cout << firstocc[u] << ' ' << firstocc[v] << ' ' << rmq(firstocc[u], firstocc[v]) << ' ' << euler[rmq(firstocc[u], firstocc[v])] << endl;
return euler[rmq(firstocc[u], firstocc[v])];
}

bool insub(int u, int v) //is u in the subtree of v?
{
if(start[v] <= start[u] && en[u] <= en[v]) return true;
return false;
}

void dfspar(int u, int p)
{
//cerr << u << ' ' << p << '\n';
st[0][u].p = p;
if(p == -1) h[u] = 0;
else h[u] = h[p] + 1;
for(int i = 0; i < adj[u].size(); i++)
{
int v = adj[u][i].v;
if(v == p) continue;
dfspar(v, u);
}
}

int LOG;

void calcpar()
{
h.resize(n);
int LG = 0; LOG = 0;
while((1<<LG) <= n) {LG++; LOG++;}
st.resize(LG);
for(int i = 0; i < LG; i++)
{
st[i].resize(n);
}
dfspar(0, -1);
//cerr << "HER" << ' ' << LG << endl;
for(int i = 1; i < LG; i++)
{
for(int j = 0; j < n; j++)
{
if(st[i-1][j].p == -1) st[i][j].p = -1;
else st[i][j].p = st[i-1][st[i-1][j].p].p;
}
}
}

int getpar(int u, ll k)
{
for(int i = LOG - 1; i >= 0; i--)
{
if(k&(1<<i))
{
u = st[i][u].p;
}
}
return u;
}

int lca(int u, int v)
{
if(h[u] > h[v]) swap(u, v);
for(int i = LOG - 1; i >= 0; i--)
{
if(st[i][v].p != -1 && h[st[i][v].p] >= h[u])
{
v = st[i][v].p;
}
}
if(u == v) return u;
for(int i = LOG - 1; i >= 0; i--)
{
if(st[i][v].p != -1 && st[i][v].p != st[i][u].p)
{
u = st[i][u].p;
v = st[i][v].p;
}
}
return st[0][u].p;
}

int distance(int u, int v)
{
int lc = lca(u, v);
return (h[u]+h[v]-2*h[lc]);
}
};
//End Tree

/* TO-DO LIST :
1. SQRT DECOMP (MO)
2. SQRT DECOMP (REAL)
3. TREE (LCA, HLD)
12. OTHER STRING STRUCTS SUCH AS PALINDROMIC TREE
12. OTHER STRING STRUCTS SUCH AS PALINDROMIC TREE, MANACHAR, Z?
14. FFT
15. Karatsuba
16. Other Flow Algo
Expand Down

0 comments on commit 94f6758

Please sign in to comment.