Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
# Heavy Path Decomposition (Enhanced)

## Overview

Enhanced Heavy Path Decomposition is an advanced tree decomposition technique that partitions a tree into heavy paths, enabling efficient path and subtree queries. It combines the power of heavy-light decomposition with advanced optimizations like persistent data structures, lazy propagation, and dynamic updates.

## Theory

### Key Concepts

1. **Heavy Paths**: Paths in tree where each node has at most one heavy child
2. **Light Edges**: Edges not on heavy paths
3. **Path Decomposition**: Tree partitioned into heavy paths
4. **Segment Trees**: Used for efficient range queries on paths

### Core Operations

1. **Decomposition**: Build heavy path decomposition
2. **Path Queries**: Query operations on tree paths
3. **Subtree Queries**: Query operations on subtrees
4. **Dynamic Updates**: Support for tree modifications

### Mathematical Foundation

- **Construction Time**: O(n) for tree with n nodes
- **Path Query**: O(log²n) for path operations
- **Subtree Query**: O(log n) for subtree operations
- **Update Time**: O(log n) for point updates

## Applications

1. **Tree Path Queries**: Efficient path sum/min/max operations
2. **Dynamic Tree Problems**: Support for tree modifications
3. **Competitive Programming**: Advanced tree algorithms
4. **Network Routing**: Tree-based routing algorithms
5. **Database Systems**: Hierarchical data structures
6. **Game Development**: Game tree algorithms

## Algorithm Implementation

### Core Functions

```python
class HeavyPathDecomposition:
def __init__(self, tree):
self.tree = tree
self.n = len(tree)
self.heavy = []
self.parent = []
self.depth = []
self.size = []
self.chain_head = []
self.pos = []
self._decompose()

def _decompose(self):
"""Build heavy path decomposition"""

def path_query(self, u, v, operation='sum'):
"""Query operation on path from u to v"""

def subtree_query(self, u, operation='sum'):
"""Query operation on subtree rooted at u"""

def update_node(self, u, value):
"""Update value at node u"""

def update_path(self, u, v, value):
"""Update values on path from u to v"""

def get_lca(self, u, v):
"""Get lowest common ancestor of u and v"""
```

## Usage Examples

### Basic Operations

```python
# Create tree and decomposition
tree = [[1, 2], [0, 3, 4], [0], [1, 5], [1], [3]]
hpd = HeavyPathDecomposition(tree)

# Path query
result = hpd.path_query(0, 5, 'sum') # Sum on path 0->5

# Subtree query
subtree_sum = hpd.subtree_query(1, 'sum') # Sum of subtree at node 1

# Update operations
hpd.update_node(3, 10) # Update node 3
hpd.update_path(0, 5, 5) # Add 5 to all nodes on path 0->5
```

### Advanced Operations

```python
# Get LCA
lca = hpd.get_lca(4, 5)

# Multiple operations
operations = ['sum', 'min', 'max']
for op in operations:
result = hpd.path_query(0, 5, op)
print(f"{op}: {result}")

# Dynamic tree modifications (future enhancement)
# hpd.add_edge(6, 2) # Add edge (not yet implemented)
# hpd.remove_edge(1, 3) # Remove edge (not yet implemented)

## Advanced Features

### 1. Persistent HPD
- Version control for tree states
- Efficient state management
- Incremental updates

### 2. Lazy Propagation
- Efficient range updates
- Batch operations
- Memory optimization

### 3. Dynamic Updates
- Support for edge additions/removals
- Efficient rebuilding
- Incremental decomposition

### 4. Performance Monitoring
- Query time analysis
- Memory usage tracking
- Optimization metrics

## Performance Analysis

### Time Complexity
- **Construction**: O(n) for tree with n nodes
- **Path Query**: O(log²n) for path operations
- **Subtree Query**: O(log n) for subtree operations
- **Update**: O(log n) for point updates

### Space Complexity
- **Storage**: O(n) for tree structure
- **Segment Trees**: O(n log n) additional space
- **Memory Efficiency**: Good for large trees

### Memory Usage
- **Efficient**: Only stores necessary information
- **Cache Friendly**: Good locality for queries
- **Compact**: Minimal memory overhead

## Visualization

### Tree Structure
- Visual representation of tree
- Show heavy paths
- Highlight light edges

### Path Queries
- Animate path query process
- Show decomposition utilization
- Visualize query decomposition

### Performance Analysis
- Show query time distribution
- Visualize memory usage
- Highlight optimization techniques

## Test Cases

### Basic Functionality
```python
def test_basic_operations():
tree = [[1, 2], [0, 3, 4], [0], [1, 5], [1], [3]]
hpd = HeavyPathDecomposition(tree)

# Test path query
result = hpd.path_query(0, 5, 'sum')
assert result >= 0 # Should be non-negative

# Test subtree query
subtree_result = hpd.subtree_query(1, 'sum')
assert subtree_result >= 0
```

### Advanced Scenarios
```python
def test_edge_cases():
# Test single node
tree1 = [[]]
hpd1 = HeavyPathDecomposition(tree1)
result1 = hpd1.path_query(0, 0, 'sum')
assert result1 == 0

# Test linear tree
tree2 = [[1], [2], [3], []]
hpd2 = HeavyPathDecomposition(tree2)
result2 = hpd2.path_query(0, 3, 'sum')
assert result2 >= 0
```

### Performance Tests
```python
def test_performance():
import time

# Large tree test
n = 10000
tree = [[] for _ in range(n)]
for i in range(1, n):
tree[i//2].append(i)

start_time = time.time()
hpd = HeavyPathDecomposition(tree)
build_time = time.time() - start_time

# Query test
start_time = time.time()
for _ in range(1000):
hpd.path_query(0, n//2, 'sum')
query_time = time.time() - start_time

assert build_time < 5.0 # Should be reasonable
assert query_time < 2.0 # Should be fast
```

## Dependencies

### Required Libraries
```python
import time
import numpy as np
from typing import List, Optional, Tuple, Dict, Any
import matplotlib.pyplot as plt
import networkx as nx
from collections import defaultdict
```

### Optional Dependencies
```python
# For advanced visualizations
import seaborn as sns
from matplotlib.animation import FuncAnimation
```

## File Structure

```
Shivansh/Heavy_Path_Decomposition_Enhanced/
├── README.md
├── heavy_path_decomposition.py
└── test_heavy_path_decomposition.py
```

## Complexity Summary

| Operation | Time Complexity | Space Complexity | Description |
|-----------|----------------|------------------|-------------|
| Construction | O(n) | O(n) | Build HPD for tree of size n |
| Path Query | O(log²n) | O(1) | Query operation on path |
| Subtree Query | O(log n) | O(1) | Query operation on subtree |
| Update Node | O(log n) | O(1) | Update value at node |
| Update Path | O(log²n) | O(1) | Update values on path |
| Get LCA | O(log n) | O(1) | Find lowest common ancestor |

## Applications in Real-World

1. **Competitive Programming**: Advanced tree algorithms
2. **Network Routing**: Tree-based routing algorithms
3. **Database Systems**: Hierarchical data structures
4. **Game Development**: Game tree algorithms
5. **Bioinformatics**: Phylogenetic tree analysis
6. **Social Networks**: Hierarchical relationship analysis

## Advanced Topics

### 1. Persistent HPD
- Version control for tree states
- Efficient state management
- Incremental updates

### 2. Dynamic HPD
- Support for edge modifications
- Efficient rebuilding
- Incremental decomposition

### 3. Compressed Representation
- Memory optimization
- Compression techniques
- Cache-friendly implementations

### 4. Specialized Variants
- Link-cut trees
- Top trees
- Euler tour trees

## Implementation Notes

1. **Heavy Path Construction**: Proper heavy child identification
2. **Segment Tree Integration**: Efficient range query support
3. **Memory Management**: Efficient tree allocation
4. **Error Handling**: Robust input validation
5. **Performance Optimization**: Cache-friendly implementation

## Future Enhancements

1. **GPU Acceleration**: CUDA/OpenCL implementations
2. **Compression**: Memory-efficient representations
3. **Distributed Processing**: Multi-node algorithms
4. **Specialized Variants**: Domain-specific optimizations
5. **Integration**: Graph algorithm libraries
Loading