Problem:
 Score : 500 points    Problem Statement We have a sequence of N integers: A_1, A_2, \cdots, A_N .  You can perform the following operation between 0 and K times (inclusive):   Choose two integers i and j such that i \neq j , each between 1 and N (inclusive). Add 1 to A_i and -1 to A_j , possibly producing a negative element.   Compute the maximum possible positive integer that divides every element of A after the operations. Here a positive integer x divides an integer y if and only if there exists an integer z such that y = xz .      Constraints  2 \leq N \leq 500  1 \leq A_i \leq 10^6  0 \leq K \leq 10^9  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  K  A_1  A_2  \cdots  A_{N-1}  A_{N}       Output Print the maximum possible positive integer that divides every element of A after the operations.        Sample Input 1 2 3
8 20      Sample Output 1 7  7 will divide every element of A if, for example, we perform the following operation:   Choose i = 2, j = 1 . A becomes (7, 21) .   We cannot reach the situation where 8 or greater integer divides every element of A .       Sample Input 2 2 10
3 5      Sample Output 2 8  Consider performing the following five operations:   Choose i = 2, j = 1 . A becomes (2, 6) .  Choose i = 2, j = 1 . A becomes (1, 7) .  Choose i = 2, j = 1 . A becomes (0, 8) .  Choose i = 2, j = 1 . A becomes (-1, 9) .  Choose i = 1, j = 2 . A becomes (0, 8) .   Then, 0 = 8 \times 0 and 8 = 8 \times 1 , so 8 divides every element of A . We cannot reach the situation where 9 or greater integer divides every element of A .       Sample Input 3 4 5
10 1 2 22      Sample Output 3 7       Sample Input 4 8 7
1 7 5 6 8 2 6 5      Sample Output 4 5

Solution (Python):
n, k =  map(int,input().split())
a_list = list(map(int,input().split()))
total = sum(a_list)

def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort(reverse=True)
    return divisors

div_list = make_divisors(total)
for div in div_list:
    b_list = [a%div for a in a_list]
    b_list.sort()
    change = sum(b_list[:(-sum(b_list)//div)])
    if change <=k:
        print(div)
        break

Solution (Python):
N, K = [int(v) for v in input().split(' ')]
A = [int(v) for v in input().split(' ')]

sum_A = sum(A)
max_A = max(A)

def make_divisor(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n // i)
    return divisors

div_list = make_divisor(sum_A)
div_list.sort(reverse=True)

for d in div_list:
    R = [a % d for a in A]

    sum_r = sum(R)
    if sum_r % d != 0:
        continue

    R.sort()
    
    flag = False 

    sub = 0
    flag = True
    for i in range(N):
        if flag and sub + R[i] > K:
            flag = False
            

        if flag:
            sub += R[i]
        else:
            sub -= (d - R[i])

    

    if not flag and sub < 0:
        continue

    print(d)
    exit()

Solution (Python):

import bisect
import heapq
import math
import random
import sys
from collections import Counter, defaultdict, deque
from decimal import ROUND_CEILING, ROUND_HALF_UP, Decimal
from functools import lru_cache, reduce
from itertools import combinations, combinations_with_replacement, product, permutations
from operator import add, mul, sub

sys.setrecursionlimit(100000)
input = sys.stdin.readline


def read_int():
    return int(input())


def read_int_n():
    return list(map(int, input().split()))


def read_float():
    return float(input())


def read_float_n():
    return list(map(float, input().split()))


def read_str():
    return input().strip()


def read_str_n():
    return list(map(str, input().split()))


def error_print(*args):
    print(*args, file=sys.stderr)


def mt(f):
    import time

    def wrap(*args, **kwargs):
        s = time.time()
        ret = f(*args, **kwargs)
        e = time.time()

        error_print(e - s, 'sec')
        return ret

    return wrap


def divisor(n):
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            yield i
            if i != n // i:
                yield n // i


@mt
def slv(N, K, A):
    S = sum(A)
    D = [n for n in divisor(S)]
    D.sort()

    ans = 0
    for d in D:
        r = []
        for a in A:
            r.append(a % d)
        r.sort()
        rr = [d - n for n in r]
        sr = [0]
        srr = [0]
        for i in range(N):
            sr.append(sr[-1] + r[i])
            srr.append(srr[-1] + rr[i])
        
        for i in range(N):
            e = sr[i+1] - sr[0]
            f = srr[N]-srr[i+1]
            if e == f and e <= K:
                ans = max(ans, d)
                break
    return ans



def main():
    N, K = read_int_n()
    A = read_int_n()
    print(slv(N, K, A))


if __name__ == '__main__':
    main()

Solution (Python):
import sys
sys.setrecursionlimit(2**31-1)
input = sys.stdin.readline
write = sys.stdout.write
LMIIS = lambda : list(map(int,input().split()))
II = lambda : int(input())
dbg = lambda *something : print(*something) if DEBUG is True else 0
DEBUG = True

def main():
    from math import sqrt, ceil
    N,K = LMIIS()
    A = LMIIS()
    suma = sum(A)
    dL = [0] * N
    dU = [0] * N
    ds = []
    for x in range(1,ceil(sqrt(suma))+1):
        
        if suma % x != 0:
            continue

        d = suma // x 
        ds.append(x)
        for i in range(N):
            dL[i] = A[i] % d
        dL.sort()
        for i in range(N):
            dU[i] = d - dL[i]

        c = 0
        l = 0
        r = N-1
        while l < r:
            
            if dL[l] == dU[r]:
                c += dL[l]
                if c > K:
                    break
                l += 1
                r -= 1
                if l >= N or r < 0:
                    break
            elif dL[l] < dU[r]:
                c += dL[l]
                if c > K:
                    break
                dU[r] -= dL[l]
                l += 1
                if l >= N:
                    break
            else:
                c += dU[r]
                if c > K:
                    break
                dL[l] -= dU[r]
                r -= 1
                if r < 0:
                    break
            
            
        if l >= r:
            print(d)
            return

    for i  in range(len(ds)-1,-1,-1):
        d = ds[i]
        for i in range(N):
            dL[i] = A[i] % d
        dL.sort()
        for i in range(N):
            dU[i] = d - dL[i]

        c = 0
        l = 0
        r = N-1
        while l < r:
            
            if dL[l] == dU[r]:
                c += dL[l]
                if c > K:
                    break
                l += 1
                r -= 1
                if l >= N or r < 0:
                    break
            elif dL[l] < dU[r]:
                c += dL[l]
                if c > K:
                    break
                dU[r] -= dL[l]
                l += 1
                if l >= N:
                    break
            else:
                c += dU[r]
                if c > K:
                    break
                dL[l] -= dU[r]
                r -= 1
                if r < 0:
                    break
            
            
        if l >= r:
            print(d)
            return


if __name__ == '__main__':
    main()

Solution (Python):
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import permutations, combinations, product, accumulate
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from fractions import gcd
import bisect

def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

N, K = MAP()
A = LIST()

def make_divisors(n):
   divisors = []
   for i in range(1, int(n**0.5)+1):
       if n % i == 0:
           divisors.append(i)
           if i != n // i:
               divisors.append(n//i)
   divisors.sort(reverse=True)
   return divisors

for i in make_divisors(sum(A)):
	
	r = sorted([x%i for x in A if x%i != 0])
	
	if r == []:
		print(i)
		break
	acc = list(accumulate(r))
	for j in range(len(r)-1):  
		down = acc[j]
		up = i*(len(r)-j-1)-(acc[-1]-acc[j])
		if abs(up-down)%i != 0:
			continue
		else:
			if max(up, down) <= K:
				print(i)
				sys.exit(0)

Solution (Python):
N, K = map(int, input().split())
As = list(map(int, input().split()))
As.sort()
S = sum(As)

ds = []
for d in range(1, 30000):
  if S%d == 0:
    ds.append(d)
    ds.append(S//d)
ds.sort()

for d in reversed(ds):
  Rs = [a%d for a in As]
  Rs.sort()
  s = sum(Rs)
  count = s//d
  r = 0
  for i in range(N-count):
    r += Rs[i]
  if r <= K:
    print(d)
    exit()

Solution (Python):
import math
from itertools import accumulate
a,b=map(int,input().split())
c=list(map(int,input().split()))

def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort(reverse = True)
    return divisors
d=make_divisors(sum(c))


m=1
for i in d:
  e=[]
  for j in range(a):
    e.append(c[j]%i)
  e.sort()
  acc_m = list(accumulate(e))
  e=[i-e[j] for j in range(a)]
  acc_p = list(accumulate(e))
  for j in range(a):
    k=acc_m[j]
    l=acc_p[-1]-acc_p[j]
    if k==l and k+l<=b*2:
      print(i)
      exit()

Solution (Python):
import sys

def main():
    input = sys.stdin.readline
    N, K = map(int, input().split())
    A = list(map(int, input().split()))

    S = sum(A)
    divs = set()
    for d in range(1, int(S**(0.5) + 1)):
        if S % d != 0:
            continue
        divs.add(d)
        divs.add(S // d)

    ans = 0
    cost = 0
    for d in divs:
        mods = []
        for a in A:
            mods.append(a % d)
        mods.sort()
        total = sum(mods)
        sub = 0
        for i, m in enumerate(mods, start=1):
            sub += m
            add = d*(N-i) - (total - sub)
            if add == sub:
                cost = sub
                break     
        if cost <= K:
            ans = max(ans, d)

    return ans


if __name__ == '__main__':
    print(main())

Solution (Python):
import fractions
import math
import sys

fastinput = sys.stdin.readline
gcd = fractions.gcd
N,K=map(int,fastinput().split())
A = [int(i) for i in fastinput().split()]
S = sum(A)
yakusu = []
for i in range(1,math.floor(math.sqrt(S))+1):
    if not S%i:
        yakusu.append(i)
        yakusu.append(S//i)

yakusu.sort(reverse = True)
for kouho in yakusu:
    amaris =[a%kouho for a in A]
    amaris.sort()
    amarisum= sum(amaris)
    y=amarisum // kouho
    if y==0:
        print(kouho)
        break
    else:
        yakuwa = 0
        for i in range(N-y):
            yakuwa += amaris[i]
        if yakuwa <= K:
            print(kouho)
            break

Solution (Python):
import sys
sys.setrecursionlimit(100000000)
def input():
    return sys.stdin.readline()[:-1]
from bisect import *
from collections import *
from heapq import *
from math import *

N, K = map(int, input().split())
A = list(map(int, input().split()))
S = sum(A)
x = [1, S]
for i in range(2, int(S**0.5)+1):
    if S % i == 0:
        x.append(i)
        x.append(S//i)
x.sort(reverse = 1)
for g in x:
    B = [a%g for a in A]
    B.sort()
    S1 = sum(B)
    S2 = 0
    for i in range(N)[::-1]:
        S1 -= B[i]
        S2 += g-B[i]
        if (S1-S2)%g == 0:
            if S2 < S1 and S1 <= K:
                print(g)
                exit()
            elif S1 <= S2 and S2 <= K:
                print(g)
                exit()

Solution (Python):
from bisect import bisect_left, bisect_right; from collections import Counter, defaultdict, deque, OrderedDict; from copy import deepcopy; from fractions import gcd; from functools import lru_cache, reduce; from math import ceil, floor; from sys import stdin, setrecursionlimit
import heapq as hq; import itertools as its; import operator as op



inf = float('inf')
input = stdin.readline


def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort()
    return divisors


def main():
    n, k = get_li()
    A = get_li()
    ds = make_divisors(sum(A))
    ans = 1
    for d in ds[1:]:
        pdiff = [0] * n
        ndiff = [0] * n
        for i, a in enumerate(A):
            pdiff[i] = a % d
            ndiff[i] = a % d - d
        hoge = list(sorted(zip(pdiff, ndiff)))
        ps = [0] + [h[0] for h in hoge]
        ns = [h[1] for h in hoge] + [0]
        pacc = list(its.accumulate(ps))
        nacc = list(reversed(list(its.accumulate(reversed(ns)))))
        for p_, n_ in zip(pacc, nacc):
            if p_ + n_ == 0 and p_ <= k:
                ans = d
    print(ans)
    return


def get_int():
    return int(input())


def get_float():
    return float(input())


def get_str():
    return input().strip()


def get_li():
    return [int(i) for i in input().split()]


def get_lf():
    return [float(f) for f in input().split()]


def get_lc():
    return list(input().strip())


def gets(n, types, sep=None):
    if len(types) == 1:
        return [types[0](input().strip()) for _ in range(n)]
    return list(zip(*(
        [t(x) for t, x in zip(types, input().strip().split(sep=sep))]
        for _ in range(n)
    )))


if __name__ == '__main__':
    setrecursionlimit(4100000)
    main()

Solution (Python):
import sys

def solve():
    input = sys.stdin.readline
    N, K = map(int, input().split())
    A = [int(a) for a in input().split()]
    A.sort()
    totalSum = 0
    for a in A: totalSum += a

    if K >= totalSum - A[N-1]: print(totalSum)
    else:
        divisor = []
        k = 1
        while k ** 2 <= totalSum:
            if totalSum % k == 0:
                divisor.append(k)
                if k ** 2 < totalSum: divisor.append(totalSum//k)
            k += 1

        divisor.sort(reverse = True)
        for d in divisor:
            need = []
            lenneed = 0
            for a in A:
                if a % d > 0: 
                    need.append(a % d)
                    lenneed += 1

            
            if lenneed == 0:
                print(d)
                break
            else:
                possible = False
                need.sort()
                needSum = [[0, 0] for _ in range(lenneed)]
                needSum[0][0] = need[0]
                needSum[lenneed -1][1] = d - need[lenneed - 1]
                for i in range(1, lenneed):
                    needSum[i][0] = needSum[i-1][0] + need[i]
                    needSum[lenneed - 1 - i][1] = needSum[lenneed - i][1] + d - need[lenneed - i - 1]
                

                for i in range(lenneed - 1):
                    if needSum[i][0] == needSum[i+1][1] and needSum[i][0] <= K:
                        possible = True
                
                if possible: 
                    print(d)
                    break

    return 0

if __name__ == "__main__":
    solve()

Solution (Python):




def get_fact(N):
  ret = set([N])
  for i in range(2,int(N**0.5)+2):
    if N%i == 0:
      ret.add(i)
      ret.add(N//i)
  return ret


def main():
  
  N,K = map(int, input().split())
  An = list(map(int, input().split()))

  
  fset = get_fact(sum(An))
  ans = 1
  for f in fset:
    Amod = [a%f for a in An]
    Amod = sorted(Amod)
    if sum(Amod[:-sum(Amod)//f]) <= K:
      ans = max(ans,f)
  return ans


if __name__ == "__main__":
  ans = main()
  print(ans)

Solution (Python):
import math
from collections import deque


def check(A, d, K):
    diff = []
    for a in A:
        if a % d != 0:
            diff.append(a % d)
    totalinc = 0
    diff.sort()
    q = deque(diff)
    cnt = 0
    while len(q):
        x = q.popleft()
        cnt += x
        totalinc += x
        while len(q) and q[-1] + totalinc >= d:
            y = q.pop()
            totalinc -= d-y
    cnt += totalinc
    return cnt <= K


def main():
    N, K = map(int, input().split())
    A = list(map(int, input().split()))
    total = sum(A)
    divs = [1, total]
    rt = int(math.sqrt(total))
    for i in range(2, rt+1):
        if total % i == 0:
            divs.append(i)
            if i**2 != total:
                divs.append(total//i)
    ans = 0
    for d in divs:
        if check(A, d, K):
            ans = max(ans, d)
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
N,K = map(int,input().split())
A = list(map(int,input().split()))
S = sum(A)
from itertools import accumulate
def check(n):
    L = [None]*N
    for i in range(N):
        L[i] = ((A[i] % n), n - (A[i] % n))
    L.sort(key=lambda x:x[0])
    acc1 = list(accumulate([L[i][0] for i in range(N)]))
    acc2 = list(accumulate([L[i][1] for i in range(N)]))
    for i in range(N):
        if acc1[i] <= K and acc2[N-1]-acc2[i] <= K:
            return True
    return False

mx = -1
import math
for i in range(math.floor(math.sqrt(S)), 0, -1):
    if S % i == 0:
        if check (i):
            mx = max(i, mx)
        if check (S // i):
            mx = max(S // i, mx)
print(mx)

Solution (Python):


import sys
from math import sqrt
from collections import deque

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7

N,K=MAP()
A=LIST()

sm=sum(A)

def divisor_set(N: int) -> set:
    """ 約数の列挙・個数 """
    
    s = {1, N}
    
    for i in range(2, int(sqrt(N))+1):
        
        if N % i == 0:
            s.add(i)
            s.add(N // i)
    return s

divs=sorted(divisor_set(sm), reverse=True)

for div in divs:
    B=[]
    for i in range(N):
        if A[i]%div!=0:
            B.append(A[i]%div)
    
    B.sort()
    B=deque(B)
    cnt=0
    while len(B):
        
        dista=B[0]%div
        
        distb=div-B[-1]%div
        
        if dista>distb:
            B[0]-=distb
            B.pop()
            cnt+=distb
        elif dista<distb:
            B[-1]+=dista
            B.popleft()
            cnt+=dista
        elif dista==distb:
            B.pop()
            B.popleft()
            cnt+=dista
    
    if cnt<=K:
        print(div)
        exit()

Solution (Python):
import sys,heapq,math,resource
from collections import deque,defaultdict
printn = lambda x: sys.stdout.write(x)
inn = lambda : int(input())
inl   = lambda: list(map(int, input().split()))
inm   = lambda:      map(int, input().split())
DBG = True 
R = 10**9 + 7

def ddprint(x):
  if DBG:
    print(x)

def setrlim():
  sys.setrecursionlimit(250000)
  soft,hard = resource.getrlimit(RLIMIT_STACK)
  
  

def prime_division(x):
    q = int(math.sqrt(x))
    a = []
    for i in range(2,q+1):
        ex = 0
        while x%i == 0:
            ex += 1
            x //= i
        if ex>0:
            a.append([i,ex])
    if x>q:
        a.append([x,1])
    return a

def foo(x):
    b = []
    for y in a:
        if y%x != 0:
            b.append(y%x)
    b.sort()
    m = k
    while m>0 and len(b)>0:
        if b[0] < x-b[-1] or (len(b)==1 and b[0]<=x//2):
            if m<b[0]:
                return False
            m -= b[0]
            b[-1] += b[0]
            b = b[1:]
            
            
            
        else:
            d = x-b[-1]
            if m<d:
                return False
            m -= d
            b[0] -= d
            b.pop()
            if b[0]==0:
                b = b[1:]
            
            
            
    return (len(b)==0)

n,k = inm()
a = inl()
sm = sum(a)
f = prime_division(sm)

facs = [1]
for z in f:
    b = z[0]
    e = z[1]
    newfacs = []
    for x in facs:
        for i in range(e+1):
            newfacs.append(x*(b**i))
    facs = newfacs

facs.sort(reverse=True)
for x in facs:
    if foo(x):
        print(x)
        exit()
print(1)

Solution (Python):
from itertools import accumulate
N, K, *A = map(int, open(0).read().split())

def check(d):
    r = sorted([v % d for v in A])
    r_inv = [d - v for v in r]    
    r_cs = [0] + list(accumulate(r))
    r_inv_cs = list(accumulate(r_inv[::-1]))[::-1] + [0]

    ret = False
    for i in range(N + 1):
        flg1 = r_cs[i] <= K
        flg2 = r_cs[i] == r_inv_cs[i]
        ret = (flg1 and flg2) or ret
    
    return ret

M = sum(A)
ans = 0
for i in reversed(range(1, int(M ** 0.5) + 1)):
    if M % i == 0 and check(i):
        ans = max(ans, i)
    if M % (M // i) == 0 and check(M // i):
        ans = max(ans, M // i)
        
print(ans)

Solution (Python):
import numpy as np


def get_prime_factorized(N):
    result    = []
    base, exp = 2, 0
    while base ** 2 <= N:
        while N % base == 0:
            N    = N // base
            exp += 1
        if exp > 0:
            result.append([base, exp])
        base, exp = base + 1, 0
    if N > 1:
        result.append([N, 1])
    return result

def re_func_divisior(prime_factorized):
    base, exp = prime_factorized.pop()
    P = re_func_divisior(prime_factorized) if prime_factorized else [[]]
    Q = [[base ** k] for k in range(exp + 1)]
    return [p + q for p in P for q in Q]

def get_list_divisor(N, reverse=True):
    try:
        prime_factorized = get_prime_factorized(N)
        res    = re_func_divisior(prime_factorized)
        result = []
        for k in res:
            for i, x in enumerate(k):
                if i == 0:
                    r = x
                else:
                    r *= x
            result.append(r)
        result = sorted(result, reverse=reverse)
    except:
        result = [N]
    return result


N, K = map(int, input().split())
A    = list(map(int, input().split()))

X = get_list_divisor(sum(A))

is_break = False

for x in X:
    POS = sorted([a % x for a in A if a % x != 0])
    NEG = [x - pos for pos in POS]
    POS_cumsum = np.cumsum(POS)
    NEG_cumsum = np.cumsum(NEG[::-1])[::-1]
    for sep in range(1, len(POS)):
        if POS_cumsum[sep-1] == NEG_cumsum[sep] and POS_cumsum[sep-1] <= K:
            is_break = True
            break
    if is_break:
        break

print(x)

Solution (Python):
N, K = map(int, input().split())
A = list(map(int, input().split()))

sumA = sum(A)
divisors = []
for i in range(1, sumA + 1):
    if i * i > sumA:
        break
    if sumA % i != 0:
        continue
    divisors.append(i)
    if sumA // i != i:
        divisors.append(sumA // i)

divisors.sort(reverse=True)

ans = 0
for d in divisors:
    costs = [a % d for a in A]
    costs.sort()
    if sum(costs[:N - sum(costs) // d]) <= K:
        print(d)
        break

Solution (Python):
N, K = map(int, input().split())
a_list = list(map(int, input().split()))

def divisors(num):
    """
    約数全列挙
    """
    divisors = []
    for i in range(1, int(num ** 0.5) + 1):
        if num % i == 0:
            divisors.append(i)
            if i != num // i:
                divisors.append(num // i)

    return divisors
sum_num = sum(a_list)
a_list.sort()
div = divisors(sum_num)
div.sort(reverse=True)
ans = 1
from itertools import accumulate
for d in div:
    mod = []
    if d == 1:
        break
    for a in a_list:
        mod.append(a % d)
    mod.sort()
    acc_m = list(accumulate(mod))
    modd = []
    for i in range(N):
        modd.append(d-mod[i])
    acc_p = list(accumulate(modd))
    flag = False
    for i in range(N-1):
        p_sum = acc_p[-1] - acc_p[i]
        n_sum = acc_m[i]
        if p_sum == n_sum and p_sum <= K:
            flag = True
    if flag:
        ans = d
        break

print(ans)

Solution (Python):
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort()
    return divisors

N,K = map(int,input().split())
A = list(map(int,input().split()))
D = sum(A)
D = make_divisors(D)[::-1]

for d in D:
    a = []
    for i in range(N):
        a.append(A[i]%d)
    k = 0
    M = max(a)
    while k <= K and M != 0:
        i = 0
        j = 0
        m = d
        M = 0
        for l in range(N):
            if 0 < a[l] < m:
                m = a[l]
                i = l
        for l in range(N-1,-1,-1):
            if a[l] > M:
                M = a[l]
                j = l
        if m == d:
            break
        if m <= d-M:
            a[i] = 0
            a[j] += m
            a[j] %= d
            k += m
        else:
            a[i] -= d-M
            a[i] %= d
            a[j] = 0
            k += d-M
    if k <= K:
        break

print(d)

Solution (Python):

N, K = map(int,input().split())
A = list(map(int,input().split()))
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)
    return divisors
ls = sorted(make_divisors(sum(A)))[::-1]


def cost(ls,n):
    ls = sorted(ls)
    
    left = 0
    right = len(ls)-1
    sm = 0
    while left < right:
        if (ls[left] + ls[right])<=n:
            op = ls[left]
            ls[left] = 0
            ls[right] += op
            left += 1
        else:
            op = n-ls[right]
            ls[right] = 0
            right -= 1
            ls[left] -= op
            if ls[left] == 0:
                left += 1


        sm += op
        
        
        
    return sm

    

for n in ls:
    if cost([a%n for a in A],n) <= K:
        print (n)
        exit()

Solution (Python):
n,k=map(int,input().split())
a=list(map(int,input().split()))

def yakusuu(a):
    yakusuu=set()
    for i in range(1,int(a**0.5)+1):
        if a%i==0:
            yakusuu.add(i)
            yakusuu.add(a//i)
    yakusuu=sorted(list(yakusuu),reverse=True)
    return yakusuu

y=yakusuu(sum(a))

from itertools import accumulate
flag=0
for i in y:
    B=[A%i for A in a]
    C=sorted(B,reverse=True)
    B=list(accumulate(sorted(B)))
    C=list(reversed(list(accumulate([(i-c)%i for c in C]))))[1:]+[0]
    for j in range(n):
        if B[j]==C[j]:
            if B[j]<=k:
                print(i)
                flag=1
                break
            break
    if flag==1:
        break

Solution (Python):
def div(n):
  ret=[]
  for i in range(1,int(n**0.5)+1):
    if n%i==0:
      ret.append(i)
      if i!=n//i:
        ret.append(n//i)
  return ret

n,k=map(int,input().split())
arr=list(map(int,input().split()))
arr=sorted(arr)
s=sum(arr)
ans=1
d=div(s)
for val in d:
  arr=sorted(arr,key=lambda x:x%val)
  parr=[]
  narr=[]
  for num in arr:
    narr.append(num%val)
    parr.append(val-num%val)
  for i in range(n-1):
    parr[i+1]+=parr[i]
    narr[i+1]+=narr[i]
  for i in range(n-1):
    ncnt=narr[i]
    pcnt=parr[-1]-parr[i]
    if ncnt!=pcnt:
      continue
    else:
      if pcnt<=k:
        ans=max(ans,val)
print(ans)

Solution (Python):
def main():
     n,k=map(int,input().split())
     a=list(map(int,input().split()))
     sum_a=sum(a)
     anskoho=[]
     for i in range(1,int(sum_a**0.5)+1):
          if sum_a%i==0:
               anskoho+=[i,sum_a//i]
     anskoho.sort(reverse=True)
     
     for i in anskoho:
          a_sub=[j%i for j in a]
          a_sub.sort()
          
          sum_L,sum_R=sum(a_sub),0
          sakai=n-1
          while sum_L!=sum_R:
               sum_L-=a_sub[sakai]
               sum_R+=i-a_sub[sakai]
               sakai-=1
          if sum_L<=k:
               print(i)
               break
if __name__ == '__main__':
     main()

Solution (Python):
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort()
    return divisors

N,K = map(int,input().split())
A = list(map(int,input().split()))
D = sum(A)
D = make_divisors(D)[::-1]

for d in D:
    a = []
    for i in range(N):
        if A[i]%d != 0:
            a.append(A[i]%d)
    a.sort()
    b = [d-x for x in a]
    b.sort()

    c1 = [0]*(len(a)+1)
    for i in range(len(a)):
        c1[i] = a[i]+c1[i-1]
    c2 = [0]*(len(b)+1)
    for i in range(len(b)):
        c2[i] = b[i]+c2[i-1]

    k = float('inf')
    for i in range(len(a)):
        if c1[i] == c2[len(a)-2-i]:
            k = c1[i]
            break
    if k <= K:
        break
print(d)

Solution (Python):
N, K = map(int, input().split())
A = list(map(int, input().split()))
sumA = sum(A)


def divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)
    divisors.sort(reverse = True)  
    return divisors

ansList = divisors(sumA)
ans = 1

for div in ansList :
    res = [a % div for a in A]
    res.sort(reverse=True)

    sumCount = sum(res)
    b = 0
    for r in res :
        sumCount -= r
        b += div - r
        if sumCount == b :
            if sumCount <= K :
                ans = div
                break
    else :
        continue
    break

print(ans)

Solution (Python):
N, K = map(int, input().split())
A = list(map(int, input().split()))

def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort(reverse=True)
    return divisors

goukei = sum(A)
candidate = make_divisors(goukei)
tmp_goukei = 0
operation = 0
answer = 1
for c in candidate:
    mod_c = sorted([a % c for a in A], reverse=True)
    sum_c = sum(mod_c)
    
    if sum_c % c != 0:
        continue
    counter = 0
    for a in mod_c:
        sum_c -= c
        counter += c - a
        if sum_c <= 0:
            break
    
    if counter <= K:
        answer = c
        break
    else:
        tmp_goukei = 0
        operation = 0
print(answer)