Buggy python submission (verdict: Time Limit Exceeded):
import bisect
import numpy as np


def main():
	class ModuloAddition (Abelian):
		def __init__(self, mod):
			self.mod = mod
		
		def operate(self, x, y):
			return (x + y) % self.mod
		
		@property
		def identity(self):
			return 0
		
		def invert(self, x):
			return (-x) % self.mod
	
	class ModuloMultiplication (Abelian):
		def __init__(self, mod):
			self.mod = mod
		
		def operate(self, x, y):
			return (x * y) % self.mod
		
		@property
		def identity(self):
			return 1
		
		def invert(self, x):
			x %= self.mod
			return self.accumulate(x, self.mod - 2)
	
	INF = 1000000007
	N, A, B, C = map(int, input().split())
	add = ModuloAddition(INF)
	mul = ModuloMultiplication(INF)
	A = mul.operate(A, mul.invert(100 - C))
	B = mul.operate(B, mul.invert(100 - C))
	C = mul.operate(C, mul.invert(100))
	
	FACT = [1]
	A_ACC = [1]
	B_ACC = [1]
	for i in range(1, 2*N):
		FACT.append(mul.operate(FACT[i-1], i))
		A_ACC.append(mul.operate(A_ACC[i-1], A))
		B_ACC.append(mul.operate(B_ACC[i-1], B))
	
	def NCK(n, k):
		if n < k:
			return 0
		return mul.cancel(FACT[n], mul.operate(FACT[n-k], FACT[k]))
		
	
	k = mul.invert(add.cancel(1, C))
	ans = 0
	for i in range(N):
		ans = add.operate(
			ans,
			mul.operate(
				i + N,
				mul.operate(
					NCK(N+i-1, i),
					add.operate(
						mul.operate(
							A_ACC[N],
							B_ACC[i]),
						mul.operate(
							A_ACC[i],
							B_ACC[N])
					)
			)))
	ans = mul.operate(ans, k)
	print(ans)


class IComparable (object):
	def compare(self, x, y):
		return -1 if x < y else 0 if x == y else 1




class LongestMonotonicSubsequenceLength (object):
	'''最長単調部分列長'''
	def __init__(self):
		# lowest_lasts[n] := n文字の単調部分列の末尾のうち、最も順位の低いもの
		self.lowest_lasts = []
	
	def append(self, item):
		'''入力列の末尾に要素を追加する'''
		update_index = bisect.bisect_right(self.lowest_lasts, item)
		if update_index < len(self.lowest_lasts):
			self.lowest_lasts[update_index] = item
		else:
			self.lowest_lasts.append(item)
	
	def extend(self, iterable):
		'''入力列の末尾に要素列を接続する'''
		for item in iterable:
			self.append(item)
	
	@property
	def length(self):
		return len(self.lowest_lasts)


import abc


class IBinaryOperator (object, metaclass=abc.ABCMeta):
	@abc.abstractclassmethod
	def operate(self, x, y):
		raise NotImplementedError


class IAssociative (IBinaryOperator):
	def _right_accumulate(self, base, x, count):
		if count < 0:
			raise ValueError('累積回数に負の値が指定されました。')
		acc = base
		while count:
			if count & 1:
				acc = self.operate(acc, x)
			count >>= 1
			x = self.operate(x, x)
		return acc
	
	def accumulate(self, x, count):
		if count < 1:
			raise ValueError('累積回数に負の値またはゼロが指定されました。')
		return self._right_accumulate(x, x, count - 1)


class ICommutative (IBinaryOperator):
	pass


class IIdentitive (IBinaryOperator):
	@abc.abstractproperty
	def identity(self):
		raise NotImplementedError


class IInvertible (IBinaryOperator):
	@abc.abstractmethod
	def invert(self, x):
		raise NotImplementedError


class ILeftCancellative (IBinaryOperator):
	@abc.abstractmethod
	def left_cancel(self, x, y):
		raise NotImplementedError


class IRightCancellative (IBinaryOperator):
	@abc.abstractmethod
	def right_cancel(self, x, y):
		raise NotImplementedError


class ICancellative (ILeftCancellative, IRightCancellative):
	@abc.abstractmethod
	def cancel(self, x, y):
		raise NotImplementedError
	
	def left_cancel(self, x, y):
		return self.cancel(y, x)
	
	def right_cancel(self, x, y):
		return self.cancel(x, y)


class Magma (IBinaryOperator):
	pass


class SemiGroup (Magma, IAssociative):
	pass


class Monoid (SemiGroup, IIdentitive):
	pass


class QuasiGroup (Magma, ICancellative):
	pass


class Loop (QuasiGroup, IIdentitive, IInvertible):
	def invert(self, x):
		return self.cancel(self.identity, x)


class Group (Monoid, Loop, IInvertible):
	def cancel(self, x, y):
		return self.operate(x, self.invert(y))
	
	def accumulate(self, x, count):
		if count < 0:
			x = self.invert(x)
			count = -count
		return self._right_accumulate(self.identity, x, count)


class Abelian (Group, ICommutative):
	pass


class Addition (Abelian):
	'''加算'''
	def operate(self, x, y):
		return x + y
	
	@property
	def identity(self):
		return 0
	
	def invert(self, x):
		return -x
	
	def cancel(self, x, y):
		return x - y
	
	def accumulate(self, x, count):
		return x * count


class Multiplication (Abelian):
	'''非ゼロに対する乗算'''
	def operate(self, x, y):
		return x * y
	
	@property
	def identity(self):
		return 1.0
	
	def invert(self, x):
		return 1.0 / x
	
	def cancel(self, x, y):
		return x / y
	
	def accumulate(self, x, count):
		return x ** count


from itertools import repeat


class UnionFind (object):
	'''Union-Find 木'''
	def __init__(
			self, op=Addition()):
		if not isinstance(op, Abelian):
			raise RuntimeError('op はアーベル群ではありません。')
		
		self.parent = []
		self.potential = []
		self.op = op
	
	def append(self):
		self.parent.append(-1)
		self.potential.append(self.op.identity)
	
	def extend(self, num_nodes):
		self.parent.extend(repeat(-1, num_nodes))
		self.potential.extend(repeat(self.op.identity, num_nodes))
	
	def root_potential(self, x):
		parent = self.parent[x]
		if 0 <= parent:
			self.parent[x], potential = self.root_potential(parent)
			self.potential[x] = self.op.operate(self.potential[x], potential)
			x = self.parent[x]
		return x, self.potential[x]
	
	def root(self, x):
		return self.root_potential(x)[0]
		
	def size(self, x):
		return -self.parent[self.root(x)]
	
	def difference(self, x, y):
		if not self.issame(x, y):
			raise RuntimeError('x と y は同じ集合に属していません。')
		return self.op.cancel(self.potential[y], self.potential[x])
	
	def unite(self, x, y, difference=None):
		if difference is None:
			difference = self.op.identity
		x, px = self.root_potential(x)
		y, py = self.root_potential(y)
		difference = self.op.cancel(difference, py)
		difference = self.op.operate(difference, px)
		if self.size(x) < self.size(y):
			x, y = y, x
			difference = self.op.invert(difference)
		self.parent[x] += self.parent[y]
		self.parent[y] = x
		self.potential[y] = difference		
	
	def issame(self, x, y):
		return self.root(x) == self.root(y)
		



if __name__ == '__main__':
	main()




Fixed submission:
import numpy as np

INF = 1000000007

def add(x, y):
	return (x + y) % INF

def sub(x, y):
	return (x - y) % INF

def mul(x, y):
	return (x * y) % INF

def power(x, y):
	return pow(x, y, INF)

def div(x, y):
	return mul(x, power(y, INF - 2))


N, A, B, C = map(int, input().split())
A = div(A, 100 - C)
B = div(B, 100 - C)
C = div(C, 100)

FACT = [1]
A_ACC = [1]
B_ACC = [1]
for i in range(1, 2*N):
	FACT.append(mul(FACT[i-1], i))
	A_ACC.append(mul(A_ACC[i-1], A))
	B_ACC.append(mul(B_ACC[i-1], B))

def NCK(n, k):
	if n < k:
		return 0
	return div(FACT[n], mul(FACT[n-k], FACT[k]))
	

k = div(1, sub(1, C))

ans = 0
for i in range(N):
	ans = add(
		ans,
		mul(
			i + N,
			mul(
				NCK(N+i-1, i),
				add(
					mul(A_ACC[N], B_ACC[i]),
					mul(A_ACC[i], B_ACC[N])
				)
		)))
ans = mul(ans, k)
print(ans)