Problem:
Score : 300 points

Problem Statement

You are given four integers A, B, C, and D. Find the number of integers between A and B (inclusive) that can be evenly divided by neither C nor D.

Constraints

1\leq A\leq B\leq 10^{18}

1\leq C,D\leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

A B C D

Output

Print the number of integers between A and B (inclusive) that can be evenly divided by neither C nor D.

Sample Input 1

4 9 2 3

Sample Output 1

2

5 and 7 satisfy the condition.

Sample Input 2

10 40 6 8

Sample Output 2

23

Sample Input 3

314159265358979323 846264338327950288 419716939 937510582

Sample Output 3

532105071133627368

Solution in Go (1.6) (judge verdict: Time Limit Exceeded)

package main

import "fmt"

func main(){
	var max, min, number1, number2, tmp1, tmp2, tmp3, result, number, x, j, i int64
	fmt.Scan(&min, &max, &number1, &number2)
	if number1 <= 1 || number2 <= 1 {
		fmt.Printf("%d", 0)
		return
	}
	result, tmp1, tmp2, tmp3, x = 0, 0, 0, 0, 0
	//範囲内の整数の数を求める
	number = max - min + 1
	//範囲内の整数の中で「C」で割り切れる最小の数を求める
	j = min % number1
	if j == 0 {//このあとの処理がminより大きい数から始まるから、minが「C」で割り切れる場合、インクリメントしておく。
		result++
	}
	tmp1 = min + number1 - j//minより大きい数で「C」で割り切れる最小の数

	if number1 != number2 {//C,Dが等しいときは片方だけ考慮するため
		j = min % number2//「D」に対しても同じことを行う。
		if j == 0 {
			result++
		}
		tmp2 = min + number2 - j
		for i = tmp2; i <= max; i += number2 {
			result++
		}
	}
	for i := tmp1; i <= max; i += number1 {
		result++
	}


	//最小公倍数を見つける
	var big, small int64
	if number1 < number2 {//大きい方と小さいほうに分け、大きいほうの数だけループで回し
	                      //素因数分解を行い、大きいほうには含まれていて、小さいほうに含まれていない数を見つける。
	                      //それを小さいほうにかけていけば最小公倍数になる。
		big = number2
		small = number1
	}else{
		big = number1
		small = number2
	}

	var min_common_multiple int64//最小公倍数
	min_common_multiple = disassembley(big, small, small)//再帰関数
	//範囲内の最小公倍数の倍数の数をxに入れる
	j = min % min_common_multiple
	if j == 0 {
		x++
	}
	tmp3 = min + min_common_multiple - j
	for i = tmp3; i <= max; i += min_common_multiple {
		x++
	}

	result -= x
	fmt.Printf("%d", number - result)
}

func disassembley(big int64, small int64, a int64) int64 {
	var k int64
	var tmp = big
	for k = 2; k <= tmp; k++ {
		if big % k == 0 {
			if small % k == 0 {
				a = disassembley(big/k, small/k, a)
				break
			}else{
				a *= k
				big /= k
				k = 1
			}
		}
	}
	return a
}