zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    小白专场-堆中的路径-python语言实现
    小白专场-堆中的路径-c语言实现
    集合及运算
    哈弗曼树与哈夫曼编码

    线性结构之习题选讲-ReversingLinkedList
    小白专场-是否同一颗二叉搜索树-python语言实现
    微信公众平台开发教程第1篇-新手解惑(转)
    GIT GUI的使用(转)
    Git操作指南(2) —— Git Gui for Windows的建库、克隆(clone)、上传(push)、下载(pull)、合并(转)
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5755970.html
Copyright © 2011-2022 走看看