Question:
Here are the numbers of a, B, c, d, and k: x, a, B, y, c, d, and gcd (x, y) = k.
Repeat the calculation, that is, x = 1, y = 2 and x = 2, y = 1.
Ideas:
First, convert B/k, d/k to the number of x, [a, B] y, [c, d], gcd (x, y) = 1.
Then we enumerate one of the smaller intervals.
Find the number of interconnectivity between another interval and it
Because there are many numbers, we need to pre-process the quality factors of each number.
Then there is the refresh theorem!
Then pay attention to the case of 0!
Code:
# Include "cstdlib" # include "cstdio" # include "cstring" # include "cmath" # include "queue" # include "algorithm" # include "iostream" using namespace std; # define ll _ int64 # define N 100000int ss [N + 2], v [N + 2]; int mark [N + 5] [10], mcnt [N + 5], c [12]; int ssb () {int cnt = 0; memset (ss, 0, sizeof (ss )); for (int I = 2; I <= N; I ++) {if (ss [I] = 0) {for (int j = I + I; j <= N; j + = I) ss [j] = 1; v [cnt ++] = I;} return cnt;} ll dfs (int k, int x, int struct, in T a, int B) {ll ans = 0; if (x = Hangzhou) {int tep = 1; for (int I = 0; I <strong; I ++) tep * = c [I]; return B/tep-a/tep;} for (int I = k + 1; I <mcnt [a]; I ++) {c [x] = mark [a] [I]; ans + = dfs (I, x + 1, clerk, a, B);} return ans ;} ll solve (int x, int y) {ll ans = 0; for (int I = 1; I <= mcnt [x]; I ++) {if (I % 2) ans + = dfs (-, I, x, y); else ans-= dfs (-, I, x, y );} return ans;} int main () {int t, cas = 1, sscnt; cin> t; sscnt = ssb (); memset (mcnt, 0, sizeof (mcnt ); For (int I = 0; I <sscnt; I ++) {for (int j = v [I]; j <= N; j + = v [I]) {mark [j] [mcnt [j] ++] = v [I] ;}} while (t --) {int a, B, c, d, k; scanf ("% d", & a, & B, & c, & d, & k ); if (k = 0) {printf ("Case % d: % d \ n", cas ++, 0); continue;} B/= k; d/= k; if (B> d) swap (B, d); ll ans = (B = 0? 0: d); for (int I = 2; I <= B; I ++) {ans + = d-I-solve (I, d );} printf ("Case % d: % I64d \ n", cas ++, ans);} return 0 ;}
[Rejection principle] hdu 1695 GCD