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 C++14 (GCC 5.4.1) (judge verdict: Accepted)


#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <array>
#include <cmath>

using namespace std;

using ll = long long int;

// GCDを計算します
template <typename NumType>
NumType calcGCD(NumType a, NumType b) {
    if (a < b) {
        NumType tmp = a;
        a = b;
        b = tmp; 
    }

    NumType r = a % b;
    while (r != 0) {
        a = b;
        b = r;
        r = a % b;
    }

    return b;
}

// 約数を数えます
template <typename NumType>
NumType cntDivisor(const NumType & num) {
    NumType cnt = 0;
    for(NumType i = 1; i * i <= num; ++i) {
        if(num % i == 0) {
            cnt++;
            if(i * i != num) cnt++;
        }
    }

    return cnt;
}

// vector< int64_t > divisor(int64_t n) {
//   vector< int64_t > ret;
//   for(int64_t i = 1; i * i <= n; i++) {
//     if(n % i == 0) {
//       ret.push_back(i);
//       if(i * i != n) ret.push_back(n / i);
//     }
//   }
//   sort(begin(ret), end(ret));
//   return (ret);
// }

// [beg, end)の範囲を，添え字indexでループするfor文に置換します
#define FOR_RANGE(index, beg, end)     for (ll index = beg; index < N; ++index)

#define DEBUG(x)     std::cout << #x << " : " << x << "\n"


ll calcLcm(ll a, ll b) {
    ll x = a * b;
 
    if (a < b){
        ll tmp = a;
        a = b;
        b = tmp;
    }
   
    ll r = a % b;
    while (r != 0) {
        a = b;
        b = r;
        r = a % b;
    }

    return x / b;
}


int main() {
    ll A, B, C, D;
    cin >> A >> B >> C >> D;

    ll lcm = calcLcm(C, D);

    ll c_div = 0, d_div = 0, lcm_div = 0;
    ll beg, end;
    beg = (A%C != 0) ? A/C + 1 : A/C;
    end = B/C;
    c_div = end - beg + 1;
    //DEBUG(c_div);
    beg = (A%D != 0) ? A/D + 1 : A/D;
    end = B/D;
    d_div = end - beg + 1;
    //DEBUG(d_div);

    beg = (A%lcm != 0) ? A/lcm + 1 : A/lcm;
    end = B/lcm;
    lcm_div = end - beg + 1;
    //DEBUG(lcm_div);

    cout << B - A + 1 - c_div - d_div + lcm_div;

    return 0;
}