We use cookies to ensure you have the best browsing experience on our website. Please read our cookie policy for more information about how we use cookies.
- Prepare
- Data Structures
- Advanced
- Rooted Tree
- Discussions
Rooted Tree
Rooted Tree
Sort by
recency
|
12 Discussions
|
Please Login in order to post a comment
using namespace std; typedef vector vi; typedef pair pii; typedef vector > vpii; typedef long long ll; typedef vector vl; typedef pair pll; typedef vector > vpll; typedef vector vs; typedef long double ld; template inline void amin(T &x, U y) { if(y < x) x = y; } template inline void amax(T &x, U y) { if(x < y) x = y; }
struct To { typedef int Vertex; Vertex to; To() { } To(Vertex to_): to(to_) { } };
template struct StaticGraph { typedef To_ To; typedef typename To::Vertex Vertex; typedef std::pair Edge; typedef const To *const_iterator;
private: int n; std::vector tos; std::vector offsets; };
class SchieberVishkinLCA { public: typedef StaticGraph Graph; typedef unsigned Word; typedef Graph::Vertex Vertex; private:
public: //g????????????? void build(const Graph &g, Vertex root) { return build(g, std::vector(1, root)); } void build(const Graph &g, const std::vector &roots) { int N = g.numVertices();
};
template struct ModInt { static const int Mod = MOD; unsigned x; ModInt(): x(0) { } ModInt(signed sig) { int sigt = sig % MOD; if(sigt < 0) sigt += MOD; x = sigt; } ModInt(signed long long sig) { int sigt = sig % MOD; if(sigt < 0) sigt += MOD; x = sigt; } int get() const { return (int)x; }
}; typedef ModInt<1000000007> mint;
struct Val { bool sign; mint x; int depth; Val() { } Val(bool sign_, mint x_, int depth_): sign(sign_), x(x_), depth(depth_) { } };
struct Sum { mint signedSum, signedDepthSum, signedCount; Sum(): signedSum(0), signedDepthSum(0), signedCount(0) { } Sum(const Val &val, int pos) { bool sign = val.sign; signedDepthSum = !sign ? val.depth : -val.depth; signedSum = !sign ? val.x : -val.x; signedCount = !sign ? 1 : -1; } Sum &operator+=(const Sum &that) { signedSum += that.signedSum; signedDepthSum += that.signedDepthSum; signedCount += that.signedCount; return *this; } Sum operator+(const Sum &that) const { return Sum(*this) += that; } };
struct Laziness { mint add0, add1; Laziness(): add0(0), add1(0) { } Laziness(mint add0_, mint add1_): add0(add0_), add1(add1_) { } Laziness &operator+=(const Laziness &that) { add0 += that.add0; add1 += that.add1; return *this; } void addToVal(Val &val, int pos_) const { val.x += add0 + add1 * val.depth; } void addToSum(Sum &sum, int left_, int right_) const { sum.signedSum += add0 * sum.signedCount + add1 * sum.signedDepthSum; } };
struct SegmentTree { vector leafs; vector nodes; vector laziness; vector leftpos, rightpos; int n, n2; void init(int n_, const Val &v = Val()) { init(vector(n_, v)); } void init(const vector &u) { n = 2; while(n < (int)u.size()) n *= 2; n2 = (n - 1) / 2 + 1; leafs = u; leafs.resize(n, Val()); nodes.resize(n); for(int i = n-1; i >= n2; -- i) nodes[i] = Sum(leafs[i*2-n], i*2-n) + Sum(leafs[i*2+1-n], i*2+1-n); for(int i = n2-1; i > 0; -- i) nodes[i] = nodes[i*2] + nodes[i*2+1]; laziness.assign(n, Laziness());
private: int getIndices(int indices[128], int i, int j) { int k = 0, l, r; if(i >= j) return 0; for(l = (n + i) >> 1, r = (n + j - 1) >> 1; l != r; l >>= 1, r >>= 1) { indices[k ++] = l; indices[k ++] = r; } for(; l; l >>= 1) indices[k ++] = l; return k; } void propagateRange(int indices[], int k) { for(int i = k - 1; i >= 0; -- i) propagate(indices[i]); } void mergeRange(int indices[], int k) { for(int i = 0; i < k; ++ i) merge(indices[i]); } inline void propagate(int i) { if(i >= n) return; laziness[i].addToSum(nodes[i], leftpos[i], rightpos[i]); if(i * 2 < n) { laziness[i * 2] += laziness[i]; laziness[i * 2 + 1] += laziness[i]; }else { laziness[i].addToVal(leafs[i * 2 - n], i * 2); laziness[i].addToVal(leafs[i * 2 + 1 - n], i * 2 + 1); } laziness[i] = Laziness(); } inline void merge(int i) { if(i >= n) return; nodes[i] = sum(i * 2) + sum(i * 2 + 1); } inline Sum sum(int i) { propagate(i); return i < n ? nodes[i] : Sum(leafs[i - n], i - n); } };
vector t_parent; vi t_seq; vector t_sign; vector t_left, t_right;
void tree_signedeulertour(const vector &g, int root) { int n = g.size(); t_parent.assign(n, -1); t_left.assign(n, -1); t_right.assign(n, -1); t_seq.assign(n * 2, -1); t_sign.assign(n * 2, false); int pos = 0;
}
int main() { int N, Q, root; scanf("%d%d%d", &N, &Q, &root), root --; vector g(N); rep(i, N-1) { int a, b; scanf("%d%d", &a, &b), a --, b --; g[a].pb(b); g[b].pb(a); } tree_signedeulertour(g, root); vi depth(N, -1); rep(ix, t_seq.size()) if(!t_sign[ix]) { int i = t_seq[ix]; depth[i] = i == root ? 0 : depth[t_parent[i]] + 1; }
}
Rust solution - work in progress here. The solution so far produces correct results, but has TLE's and is in need of some optimization. I'm looking at compressing the sparse branches while preserving the ability to calculate node values on the fly.
Things I wish the problem description had told me:
+=
:.value += v + d * k;
include
include
include
include
include
using namespace std;
long Max = 1000000; long N; long Root;
struct Node { long long value = 0; long height = 0; vector childNoes; };
void DeLinkParentFromChild(long R, Node* arr, long P, long height) { Node* node = &arr[R]; node->height = height; int size = node->childNoes.size(); for(long i = 0; i < size; ++i) { long index = node->childNoes[i]; if(index > N) continue;
}
void AddValue(Node* arr, long T, int K, long long value) { Node* node = &arr[T]; node->value += value;
}
void GetSum(Node* arr, long A, long B, long long& sum, bool& bFound) { while (arr[A].height > arr[B].height) { Node* node = &arr[A]; sum += node->value;
}
int main() {
long E; long R;
}
Solution in C++
I'm having difficulty understanding this editorial, which means I may not understand the question. I don't see how an update can be done in log n time. It seems like it would be more efficient to simply update the array, not the sums in a BIT.
Consider the array with positions 1-17. Using a BIT, updating index 4 would cause updates to 8 and 16. All of 4's descendants would have this same cost. Therefore the updates would take nlog n time, not log n. Using an array, updates would take n time (n being the nodes you need to update) because you're simply updating indexes. Note that for this post, I’m not counting the cost of finding the descendants of a node.
Any thoughts?