HDU 5812 Distance

来源:互联网 发布:怎样提高淘宝店铺销量 编辑:程序博客网 时间:2024/04/29 16:04


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.
 

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.
 

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
12I 20I 15Q 30I 30Q 30D 10Q 27I 15D 15D 20D 30Q 50
 

Sample Output
Case #1:103-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, rusing 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;}


0 0
原创粉丝点击