Problem Description
In number theory, a prime is a positive integer greater than 1 that has no positive divisors other than 1 and itself. The distance between two positive integers x and y, denoted by d(x, y), is defined as the minimum number of multiplications by a prime or divisions (without a remainder) by a prime one can perform to transform x into y. For example, d(15, 50) = 3, because 50 = 15 * 2 * 5 / 3, and you have to perform two multiplications (*2, *5) and one division (/3) to transform 15 into 50.
For a set S of positive integers, which is initially empty, you are asked to implement the following types of operations on S.
1. I x: Insert x into S. If x is already in S, just ignore this operation.
2. D x: Delete x from S. If x is not in S, just ignore this operation.
3. Q x: Find out a minimum z such that there exists a y in S and d(x, y) = z.
For a set S of positive integers, which is initially empty, you are asked to implement the following types of operations on S.
1. I x: Insert x into S. If x is already in S, just ignore this operation.
2. D x: Delete x from S. If x is not in S, just ignore this operation.
3. Q x: Find out a minimum z such that there exists a y in S and d(x, y) = z.
Input
The input contains multiple test cases. The first line of each case contains an integer Q (1 <= Q <= 50000), indicating the number of operations. The following lines each contain a letter ‘I’, ‘D’ or ‘Q’, and an integer x (1 <= x <= 1000000).
Q = 0 indicates the end of the input.
The total number of operations does not exceed 300000.
Q = 0 indicates the end of the input.
The total number of operations does not exceed 300000.
Output
For each case, output “Case #X:” first, where X is the case number, starting from 1. Then for each ‘Q’ operation, output the result in a line; if S is empty when a ‘Q’ operation is to perform, output -1 instead.
Sample Input
12 I 20 I 15 Q 30 I 30 Q 30 D 10 Q 27 I 15 D 15 D 20 D 30 Q 5 0
Sample Output
Case #1: 1 0 3 -1开200w个堆来搞定插入和删除,操作的效率都是sqrt(x),把x拆了放在每个位置上,然后记下最小距离。询问的时候都找一遍就好了。#include<set> #include<map> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<bitset> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define rep(i,j,k) for (int i = j; i <= k; i++) #define per(i,j,k) for (int i = j; i >= k; i--) #define lson x << 1, l, mid #define rson x << 1 | 1, mid + 1, r using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const double eps = 1e-8; const int INF = 0x7FFFFFFF; const int mod = 1e9 + 7; const int N = 1e6 + 1; int T, n, m, t, cas = 0, x, y; int a[N], f[N], g[N], gg[N], cnt[N], sum; char s[2]; priority_queue<int, vector<int>, greater<int> > p[N][2]; void get_prime() { cnt[1] = t = 0; rep(i, 2, N - 1) { if (!f[i]) { a[t++] = i; cnt[i] = 1; } for (int j = 0; j < t&&i*a[j] < N; j++) { f[i*a[j]] = 1; cnt[i*a[j]] = cnt[i] + 1; if (i%a[j] == 0) break; } } } void clear(int x) { rep(i, 0, 1) while (!p[x][i].empty()) p[x][i].pop(); } int get(int x) { if (gg[x] < cas) gg[x] = cas, clear(x); while (!p[x][0].empty() && !p[x][1].empty() && p[x][0].top() == p[x][1].top()) p[x][0].pop(), p[x][1].pop(); return p[x][0].empty() ? INF / 2 : p[x][0].top(); } int main() { get_prime(); while (scanf("%d", &n), n) { printf("Case #%d:\n", ++cas); sum = 0; while (n--) { scanf("%s%d", s, &x); if ((s[0] == 'I' || s[0] == 'D')&&g[x] < cas) g[x] = cas, f[x] = 0; if (s[0] == 'I' && !f[x]) { sum++; f[x] = 1; y = sqrt(1.0*x); rep(i, 1, y) { if (x%i) continue; if (gg[i] < cas) gg[i] = cas, clear(i); if (gg[x / i] < cas) gg[x / i] = cas, clear(x / i); if (i*i == x) p[i][0].push(cnt[i]); else { p[i][0].push(cnt[x / i]); p[x / i][0].push(cnt[i]); } } } if (s[0] == 'D' && f[x]) { sum--; f[x] = 0; y = sqrt(1.0*x); rep(i, 1, y) { if (x%i) continue; if (i*i == x) p[i][1].push(cnt[i]); else { p[i][1].push(cnt[x / i]); p[x / i][1].push(cnt[i]); } } } if (s[0] == 'Q') { if (!sum) { printf("-1\n"); continue; } y = sqrt(1.0*x); int ans = INF; rep(i, 1, y) { if (x%i) continue; ans = min(ans, get(i) + cnt[x / i]); ans = min(ans, get(x / i) + cnt[i]); } printf("%d\n", ans); } } } return 0; }