P3172 [CQOI2015] Number selected from
label
- Inclusion-exclusion
- Memory search
Foreword
- Good question - can teach after inversion Du screen, you can then push the formula dp! !
Concise meaning of the questions
- Given \ (n-, K, L, R & lt \) , you need to obtain, from the request interval \ ([L, R] \ ) is selected in \ (n-\) number and their \ (gcd = k \ ) the number of programs. (Repeat number selected)
Thinking
- We assume that a set of sample, \ (= n-2, K =. 3, L = 2, 10 = R & lt \) . So we need from \ ([2,10] \) to select two numbers, making their \ (gcd = 2 \) . One obvious thing is that no matter how we choose, choose a certain number of these are \ (k \) multiples.
- We found that we assume that the sample, k = 3,6,9 are multiples of 3, the number is assumed to be \ (X \) , where \ (X = 3 \) . So we list all options, a total of \ (x ^ n = 3 ^ 2 = 9 \) kinds of programs are: (3,3), (3,6), (3,9), (6 , 3), (6,6), (6,9), (9,3), (9,6), (9,9). Obviously, there are some \ (gcd \) apparently 3, there are some 6, some even 9.
Now set \ (f (i) \) for a given \ (n-, K, L, R & lt \) , to choose the \ (n-\) number and (gcd = i \) \ number of programs. Still according to the above examples, \ (F (2) = ^ 2. 3-F (. 6) -f (. 9) \) (wondering about how this equation come). So order \ (x = [L, R ] \) in \ (I \) number multiple of, in accordance with the above examples, it is easy to know
\ [f (i) = x ^ nf (2 * i) -f (3 * i) -...- f (m * i) (m * i <= R) \]Here to talk about the method for finding x. \ (X = \ FRAC Ri- \ FRAC-L {I}. 1 \) . how this formula may be exemplified as to know their
- This is a recursive, obviously, when the \ (k = 1, R = 1e9 \) , the recursion constant T. It was optimized. Breakthrough is optimized sentence: \ (of HL <= 10. 5 ^ \) . Then we have an important property: from \ ([l, r] \ ) selected several different numbers, they \ (gcd \) does not exceed \ (RL \) . Know the nature of our \ (f (x) \) can not have the \ (f (2 * i) \) have been taken into account \ (f (m * i) (m * i <= R) \) , because \ (m * i \) simply can not be \ (GCD \) , so that only the \ (f (2 * i) \) taking into account the \ (f (m * i) (m * i <= RL ) \) , but it needs a little change.
- Memories \ (f (i) \) is defined, which contains the same number of case of selecting. So we only choose to calculate the number of different situations, so you can use the above said \ (gcd \) character, simply select the number of the last subtract the same number of programs. However a lot of trouble, the number is the same protocol set p, when n = 1, p is 0 obviously, when n> = 2, we need to consider multiple of [L, R] of the interval k, and combinations mathematical calculations. A lot of trouble. There is a simplified method:
Is directly to the L, R divided by k, then it becomes to find gcd == 1, the number of programs in the new section in. After this, the number of elements of the protocol is repeated calculations is very good, because k = 1, and only a prime number 1, so the elements can only be repeated 1, L = 1 as long as the new and to choose the number of 2 or more, then the program number to +1, it's that simple.
Precautions
- Direct subtraction modulo go wrong, we should add another module modulo
to sum up
- From \ ([l, r] \ ) select a plurality of different numbers, their \ (GCD \) does not exceed \ (RL \)
AC Code
#include <cstdio>
#include <unordered_map>
using namespace std;
const int mod = 1000000007;
int ksm(int a, int b) {
int base = a, ans = 1;
while (b) {
if (b & 1)
ans = 1ll * ans * base % mod;
base = 1ll * base * base % mod;
b >>= 1;
}
return ans;
}
int n, k, l, r;
unordered_map<int, int> rec;
int f(int k) {
if (rec[k] != 0)
return rec[k];
int x = r / k - (l - 1) / k;
int ans = ksm(x, n) - x;
for (int i = 2; i * k <= r - l; i++) ans = (ans - f(i * k) + mod) % mod;
return rec[k] = ans;
}
void solve() {
scanf("%d%d%d%d", &n, &k, &l, &r);
l = (l % k == 0 ? l / k : l / k + 1);
r /= k;
k = 1;
printf("%d", f(k) + (l == 1 && n >= 2));
}
int main() {
solve();
return 0;
}