zoukankan      html  css  js  c++  java
  • HDU 5812 Distance

    从a变到b,也就是将a一直除素因子,除到1为止,然后乘b的素因子,一直乘到b。

    但是gcd(a,b)部分是不用除下去的。所以d(a,b)=a/gcd(a,b)的素因子个数+b/gcd(a,b)的素因子个数。

    然后....脑洞开始......

    枚举这个因子P,然后去计算a/P的素因子个数+b/P的素因子个数 最小值,也就是要在集合中寻找到一个b,使得式子取得最小值。

    然后....可以搞一个数组 c[因子][素因子个数]=多少种情况 来存储集合中的信息。 然后删除,插入的时候维护这个数组即可。具体看看代码。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-8;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    inline int read()
    {
        char c = getchar();  while(!isdigit(c)) c = getchar();
        int x = 0;
        while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
        return x;
    }
    
    const int maxn=1000010;
    int f[maxn],c[maxn][22],fac[maxn],sz;
    bool m[maxn];
    queue<int>Q;
    
    bool prime(int x)
    {
        if(x==1) return 0;
        for (int i=2;i*i<=x;i++) if(x%i==0) return 0;
        return 1;
    }
    
    void pre()
    {
        memset(f,0,sizeof f);
        for(int i=2;i<=1000000;i++)
        {
            if(!prime(i)) continue; f[i]=1;
            int u=i+i; while(u<=1000000) { int t=u; while(t%i==0) f[u]++,t=t/i; u=u+i; }
        }
    }
    
    void get(int x)
    {
        sz=0;
        for(int i=1;i*i<=x;i++)
        {
            if(x%i!=0) continue; int x1=i,x2=x/i;
            fac[sz++]=x1; if(x2!=x1) fac[sz++]=x2;
        }
    }
    
    void Insert(int x) { m[x]=1; get(x); for(int i=0;i<sz;i++) c[fac[i]][f[x/fac[i]]]++; }
    void Delete(int x) { m[x]=0; get(x); for(int i=0;i<sz;i++) c[fac[i]][f[x/fac[i]]]--; }
    
    void Find(int x)
    {
        int ans=60; get(x);
        for(int i=0;i<sz;i++) for(int j=0;j<=20;j++)
            if(c[fac[i]][j]) ans=min(ans,j+f[x/fac[i]]);
        if(ans==60) ans=-1; printf("%d
    ",ans);
    }
    
    int main()
    {
        pre(); int cas=1,n;
        while(~scanf("%d",&n))
        {
            if(n==0) break; printf("Case #%d:
    ",cas++);
            memset(c,0,sizeof c); memset(m,0,sizeof m);
            for(int i=1;i<=n;i++)
            {
                char op[5]; int x; scanf("%s%d",op,&x);
                if(op[0]=='I') { if(m[x]) continue; Insert(x); }
                else if(op[0]=='D') { if(!m[x]) continue; Delete(x); }
                else Find(x);
            }
        }
        return 0;
    }
  • 相关阅读:
    ACM学习历程—UESTC 1218 Pick The Sticks(动态规划)(2015CCPC D)
    ACM学习历程—UESTC 1217 The Battle of Chibi(递推 && 树状数组)(2015CCPC C)
    A*算法的实现
    codevs1011 数的计算 2001年NOIP全国联赛普及组
    一场ACM一场梦——我的一年
    HDU 4422 The Little Girl who Picks Mushrooms ( 模拟)
    HDU4277 USACO ORZ(dfs+set)
    HDU4272LianLianKan(dfs)
    HDU4268 Alice and Bob(贪心+multiset)
    hdu 5444 Elven Postman(二叉树)——2015 ACM/ICPC Asia Regional Changchun Online
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5759020.html
Copyright © 2011-2022 走看看