Integers Have Friends (Codeforces 1548B)
Tags: Math, divide and conquer

British mathematician John Littlewood once said about Indian mathematician Srinivasa Ramanujan that "every positive integer was one of his personal friends."It turns out that positive integers can also be friends with each other! You are given an array $$$a$$$ of distinct positive integers. Define a subarray $$$a_i, a_{i+1}, \ldots, a_j$$$ to be a friend group if and only if there exists an integer $$$m \ge 2$$$ such that $$$a_i \bmod m = a_{i+1} \bmod m = \ldots = a_j \bmod m$$$, where $$$x \bmod y$$$ denotes the remainder when $$$x$$$ is divided by $$$y$$$.Your friend Gregor wants to know the size of the largest friend group in $$$a$$$.

Input: Each test contains multiple test cases. The first line contains the number of test cases $$$t$$$ ($$$1 \le t \le 2\cdot 10^4$$$). Each test case begins with a line containing the integer $$$n$$$ ($$$1 \le n \le 2 \cdot 10^5$$$), the size of the array $$$a$$$.The next line contains $$$n$$$ positive integers $$$a_1, a_2, \ldots, a_n$$$ ($$$1 \le a_i \le {10}^{18}$$$), representing the contents of the array $$$a$$$. It is guaranteed that all the numbers in $$$a$$$ are distinct.It is guaranteed that the sum of $$$n$$$ over all test cases is less than $$$2\cdot 10^5$$$.

Output: Your output should consist of $$$t$$$ lines. Each line should consist of a single integer, the size of the largest friend group in $$$a$$$.

Note: In the first test case, the array is $$$[1,5,2,4,6]$$$. The largest friend group is $$$[2,4,6]$$$, since all those numbers are congruent to $$$0$$$ modulo $$$2$$$, so $$$m=2$$$.In the second test case, the array is $$$[8,2,5,10]$$$. The largest friend group is $$$[8,2,5]$$$, since all those numbers are congruent to $$$2$$$ modulo $$$3$$$, so $$$m=3$$$.In the third case, the largest friend group is $$$[1000,2000]$$$. There are clearly many possible values of $$$m$$$ that work.

Sample Inputs:
4
5
1 5 2 4 6
4
8 2 5 10
2
1000 2000
8
465 55 3 54 234 12 45 78

Sample Outputs:
3
3
2
6

Solution (Python):
from math import gcd

def solve(arr, n):
    if n == 1:
        print(1)
        return
    best = 1
    sub_arr = []
    res = [1]
    for x in range(n - 1):
        temp = abs(arr[x] - arr[x + 1])
        new_arr = []
        for (cnt, divisor) in sub_arr:
            new = gcd(temp, divisor)
            if new > 1:
                new_arr.append((cnt + 1, new))
                res.append(cnt + 1)
                temp //= new
        sub_arr = new_arr
        if temp > 1:
            sub_arr.append((2, temp))
            res.append(2)
    print(max(res))
for y in range(int(input())):
    n = int(input())
    arr = list(map(int, input().split()))
    solve(arr, n)

Solution (Python):
from math import gcd

def solve(arr, n):
    if n == 1:
        print(1)
        return
    best = 1
    sub_arr = []
    res = [1]
    for x in range(n - 1):
        temp = abs(arr[x] - arr[x + 1])
        new_arr = []
        for (cnt, divisor) in sub_arr:
            new = gcd(temp, divisor)
            if new > 1:
                new_arr.append((cnt + 1, new))
                res.append(cnt + 1)
                temp //= new
        sub_arr = new_arr
        if temp > 1:
            sub_arr.append((2, temp))
            res.append(2)
    print(max(res))
for y in range(int(input())):
    n = int(input())
    arr = list(map(int, input().split()))
    solve(arr, n)

Solution (Python):
import math
for _ in range(int(input())):
    n = int(input())
    a = [int(x) for x in input().split()]
    b = [1] + [abs(a[i] - a[i - 1]) for i in range(1, n)]
    cur = {1: 0}
    ans = 0
    for i in range(1, n):
        g = b[i]
        d = {}
        d[g] = i
        if g != 1:
            tmp = sorted(list(cur.keys()), reverse=True)
            for j in tmp:
                g = math.gcd(g, j)
                if g not in d:
                    d[g] = cur[j]
                if g == 1:
                    ans = max(ans, i - cur[j])
                    break
        cur = d.copy()
    print(ans + 1)