Skip to content

Commit

Permalink
Added persistent arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
pin3da committed Aug 19, 2016
1 parent 97014ef commit abb937a
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 0 deletions.
34 changes: 34 additions & 0 deletions codes/Data structures/persistent array.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
struct node {
node *l, *r;
int val;

node (int x) : l(NULL), r(NULL), val(x) {}
node () : l(NULL), r(NULL), val(-1) {}
};

typedef node* pnode;

pnode update(pnode cur, int l, int r, int at, int what) {
pnode ans = new node();

if (cur != NULL) {
*ans = *cur;
}
if (l == r) {
ans-> val = what;
return ans;
}
int m = (l + r) >> 1;
if (at <= m) ans-> l = update(ans-> l, l, m, at, what);
else ans-> r = update(ans-> r, m + 1, r, at, what);
return ans;
}

int get(pnode cur, int l, int r, int at) {
if (cur == NULL) return 0;
if (l == r) return cur-> val;
int m = (l + r) >> 1;
if (at <= m) return get(cur-> l, l, m, at);
else return get(cur-> r, m + 1, r, at);
}

Binary file modified codes/notebook.pdf
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <bits/stdc++.h>
#define endl '\n'
#define debug(x) cout << #x " = " << (x) << endl

using namespace std;

const int MLEN = 2 * 100000 + 100;
const int MN = MLEN * 20; // Mlen * log (Mlen)

struct node {
node *l, *r;
int val;

node (int x) : l(NULL), r(NULL), val(x) {}
node () : l(NULL), r(NULL), val(-1) {}
};

typedef node* pnode;

pnode update(pnode cur, int l, int r, int at, int what) {
pnode ans = new node();

if (cur != NULL) {
*ans = *cur;
}
if (l == r) {
ans-> val = what;
return ans;
}
int m = (l + r) >> 1;
if (at <= m) ans-> l = update(ans-> l, l, m, at, what);
else ans-> r = update(ans-> r, m + 1, r, at, what);
return ans;
}

int get(pnode cur, int l, int r, int at) {
if (cur == NULL) return 0;
if (l == r) return cur-> val;
int m = (l + r) >> 1;
if (at <= m) return get(cur-> l, l, m, at);
else return get(cur-> r, m + 1, r, at);
}

pnode version[MLEN];
int p[MLEN];

int main() {
ios_base::sync_with_stdio(false);cin.tie(NULL);

int n; cin >> n;
int len = 0;
for (int i = 0; i < n; ++i) {
char type; cin >> type;
if (type == '-') {
len--;
} else {
int x; cin >> x;
if (len == 0) {
version[len] = update(NULL, 0, MN, x, 1);
} else {
int lv = p[len - 1];
version[len] = update(version[lv], 0, MN, x, len + 1);
p[len] = get(version[lv], 0, MN, x);
}
len++;
}
cout << (len > 0 ? p[len - 1] : 0) << endl;
}

return 0;
}
34 changes: 34 additions & 0 deletions test/persistent_array.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
struct node {
node *l, *r;
int val;

node (int x) : l(NULL), r(NULL), val(x) {}
node () : l(NULL), r(NULL), val(-1) {}
};

typedef node* pnode;

pnode update(pnode cur, int l, int r, int at, int what) {
pnode ans = new node();

if (cur != NULL) {
*ans = *cur;
}
if (l == r) {
ans-> val = what;
return ans;
}
int m = (l + r) >> 1;
if (at <= m) ans-> l = update(ans-> l, l, m, at, what);
else ans-> r = update(ans-> r, m + 1, r, at, what);
return ans;
}

int get(pnode cur, int l, int r, int at) {
if (cur == NULL) return 0;
if (l == r) return cur-> val;
int m = (l + r) >> 1;
if (at <= m) return get(cur-> l, l, m, at);
else return get(cur-> r, m + 1, r, at);
}

6 changes: 6 additions & 0 deletions test/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#! /bin/bash

cp ../codes/Data\ structures/persistent\ array.cc persistent_array.cc
g++ test_persistent_array.cc -o test_pa
./test_pa
rm test_pa
41 changes: 41 additions & 0 deletions test/test_persistent_array.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <bits/stdc++.h>

#include "persistent_array.cc"

using namespace std;

void free_memory(pnode node) {
if (node == NULL) return;
free_memory(node->l);
free_memory(node->r);
delete node;
}

void random_values() {
int max_len = 100;
vector<int> data(max_len);
pnode root = NULL;
for (int i = 0; i < data.size(); ++i) {
data[i] = random();
root = update(root, 0, max_len, i, data[i]);
}

vector<int> data2 = data;
int pos = random() % data.size();
data2[pos] = random();
pnode ant = root;
root = update(root, 0, max_len, pos, data2[pos]);
for (int i = 0; i < max_len; ++i) {
assert(get(root, 0, max_len, i) == data2[i]);
assert(get(ant, 0, max_len, i) == data[i]);
}
}

int main() {
int seed = time(NULL);
printf("Random seed = %d\n", seed);
srand(seed);
random_values();
printf("Everything OK (random seed = %d).\n", seed);
return 0;
}

0 comments on commit abb937a

Please sign in to comment.