• HDU5812 Distance 构造,预处理


    分析:怎么看都是超时,但是可以先筛一遍1e6以内的每个数的最小素数

            算出每个数由多少个素数组成,然后应用,c[1e6][20]

            就是题解的那一套,参照题解,比赛的时候没有想到好的办法筛一个数的因子,醉了

            然后赛后发现,预处理因子肯定超时,虽然是O(nlogn)的,但是n是1e6啊,常数太大

           而且单组操作只有5e4,所以暴力sqrt(x)即可

    #include <iostream>
    #include <vector>
    #include <queue>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N = 1e6+1;
    int c[N][21],tot,prime[80000],mn[N],cnt[N],q,kase;
    bool check[N];
    char op[5];
    void getprime()
    {
        for(int i=2; i<=N-1; ++i)
        {
            if(!check[i])mn[i]=prime[++tot]=i;
            for(int j=1; j<=tot; ++j)
            {
                if(i*prime[j]>N-1)break;
                check[i*prime[j]]=true;
                mn[i*prime[j]]=prime[j];
                if(i%prime[j]==0)break;
            }
        }
    }
    void getcnt()
    {
        for(int i=2; i<=N-1; ++i)
        {
            int tmp=i;
            while(tmp!=1)++cnt[i],tmp/=mn[tmp];
        }
    }
    int main()
    {
        getprime();
        getcnt();
        memset(mn,0,sizeof(mn));
        while(~scanf("%d",&q),q)
        {
            printf("Case #%d:
    ",++kase);
            memset(c,0,sizeof(c));
            int ttt=0;
            for(int i=0; i<q; ++i)
            {
                int x;
                scanf("%s%d",op,&x);
                if(op[0]=='I')
                {
                    if(mn[x]==kase)continue;
                    mn[x]=kase;++ttt;
                    for(int j=1; j*j<=x; ++j)
                    {
                        if(x%j)continue;
                        ++c[j][cnt[x/j]];
                        if(x/j!=j)++c[x/j][cnt[j]];
                    }
                }
                else if(op[0]=='D')
                {
                    if(mn[x]!=kase)continue;
                    mn[x]=0;--ttt;
                    for(int j=1; j*j<=x; ++j)
                    {
                        if(x%j)continue;
                        --c[j][cnt[x/j]];
                        if(x/j!=j)--c[x/j][cnt[j]];
                    }
                }
                else
                {
                    if(ttt==0){printf("-1
    ");continue;}
                    int ans=100;
                    for(int j=1; j*j<=x; ++j)
                    {
                        if(x%j)continue;
                        for(int k=0; k<=20; ++k)
                        {
                            if(c[j][k])
                            {
                                ans=min(ans,k+cnt[x/j]);
                                break;
                            }
                        }
                        if(x/j!=j)
                        {
                            for(int k=0; k<=20; ++k)
                            {
                                if(c[x/j][k])
                                {
                                    ans=min(ans,k+cnt[j]);
                                    break;
                                }
                            }
                        }
                    }
                    if(ans==100)ans=-1;
                    printf("%d
    ",ans);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Find the Smallest K Elements in an Array
    Count of Smaller Number
    Number of Inversion Couple
    Delete False Elements
    Sort Array
    Tree Diameter
    Segment Tree Implementation
    Java Programming Mock Tests
    zz Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
    Algorithm about SubArrays & SubStrings
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5755970.html
Copyright © 2020-2023  润新知