------
## 最终结论
```python
def longest_dup_substring(S: str) -> str:
    def search(length):
        seen = set()
        current_hash = 0
        base = 256
        mod = 2**63 - 1
        
        for i in range(length):
            current_hash = (current_hash * base + ord(S[i])) % mod
        
        seen.add(current_hash)
        
        baseL = pow(base, length, mod)
        
        for start in range(1, len(S) - length + 1):
            current_hash = (current_hash * base - ord(S[start - 1]) * baseL + ord(S[start + length - 1])) % mod
            if current_hash in seen:
                return start
            seen.add(current_hash)
        
        return -1

    left, right = 1, len(S)
    start_index = -1
    
    while left <= right:
        mid = (left + right) // 2
        if search(mid) != -1:
            start_index = search(mid)
            left = mid + 1
        else:
            right = mid - 1

    return S[start_index:start_index + (left - 1)] if start_index != -1 else ""
```