• LightOJ 1341 Aladdin and the Flying Carpet 数学


    题意:给个矩形的面积a,和矩形的最小边长b,问有多少种矩形的方案(不能是正方形)

    分析:a可以写成x,y,因为不能是正方形,所以设x<y,那么x<sqrt(a),y>sqrt(a)

            所以找到所有小于sqrt(a)的因子,看有几个大于等于b的就是方案数

            因子可以由数的唯一分解定理,求得

    具体 : 先筛一遍1e6以内的素数,有线性筛,然后分解a,然后dfs找所有的小于sqrt(a)的因子,

              由于前12个素数的乘积大于1e12了,所以这部分复杂度,大概是O(2^12)(一般还要略大,不过大不了多少,数组要开大)左右

             可以用这个估计(因为是求小于sqrt(a)的,可以除以2,当然这是空间常数)

              所以这部分复杂度是O(T*2^12)满的话(4000*4000)大概也就是几百万,这部分可以忽略不计

              主要的复杂度在分解素数里,因为1e6里面大概有7w多素数,这部分复杂度(最坏的情况a是大素数),大概是4000*70000,可以卡过,由于不可能都是这种数据

              所以还是可以过的

    吐槽:然后我看了看网上的代码,都是先求出总的,然后暴力扫b减,结果居然过了,b是sqrt(a)的级别,是百万,4000*1e6,是4e9,TLE

            出题人太良心,没有卡这种的QAQ,感觉略坑啊

       

    #include <cstdio>
    #include <iostream>
    #include <ctime>
    #include <vector>
    #include <cmath>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    const int N=1e6+5;
    const int INF=0x3f3f3f3f;
    int cnt;
    bool v[N];
    LL prime[80000];
    void getprime(){
      for(int i=2;i*i<=N-5;++i)
        if(!v[i])
          for(int j=i*i;j<=N-5;j+=i)
            v[j]=1;
      for(int i=2;i<=N-5;++i)
      if(!v[i])prime[++cnt]=i;  
    }
    vector<LL>fac[2];
    int divisors[5000],tot;
    LL k;
    void dfs(int pos,LL res){
       if(pos==fac[0].size()){
          divisors[++tot]=res;
          return;
       }
       for(LL i=0,now=1;i<=fac[1][pos];now*=fac[0][pos],++i){
         if(now*res>=k)break;
         dfs(pos+1,res*now);
       }
    }
    int main()
    {
        getprime();
        int cas=0,T;
        scanf("%d",&T);
        while(T--){
           printf("Case %d: ",++cas);
           LL a,b;
           scanf("%lld%lld",&a,&b);
           k=sqrt(a);
           if(k*k!=a)++k;
           if(b>=k){
            printf("0
    ");
            continue;
           }
           LL t=a;
           fac[0].clear(),fac[1].clear();
           for(int i=1;i<=cnt&&prime[i]*prime[i]<=t;++i){
             if(t%prime[i])continue;
             int tmp=0;
             fac[0].push_back(prime[i]);
             while(t%prime[i]==0)++tmp,t/=prime[i];
             fac[1].push_back(tmp);
           }
           if(t>1){
            fac[0].push_back(t);
            fac[1].push_back(1);
           }
           tot=0;
           dfs(0,1);
           int ans=0;
           for(int i=1;i<=tot;++i)
              if(divisors[i]>=b)++ans;
          printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

              

           

  • 相关阅读:
    mybatis-plus
    AOP中Cache操作实现
    ab和webbench的安装以及使用
    git commit的提交规范
    CGI、FastCGI、PHP-CGI与PHP-FPM的概念以及各个之间的关系
    PHP垃圾回收机制(GC)
    PhpStorm中php文件如何在console中运行
    ELK-logstash导入数据以及配合kibana使用
    领扣刷题——关于数
    Uncaught SyntaxError: Illegal return statement
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5382248.html
Copyright © 2020-2023  润新知