zoukankan      html  css  js  c++  java
  • UVA11752 The Super Powers —— 数论、枚举技巧

    题目链接:https://vjudge.net/problem/UVA-11752

    题意:

    一个超级数是能够至少能表示为两个数的幂,求1~2^64-1内的超级数。

    题解:

    1.可知对于 n = a^b,如果b是合数,那么n同样可以表示为: n = (a^k)^c,其中k*c = b。所以只需要枚举底数,然后再枚举指数,如果指数为合数,那么它就是一个超级数。

    2.由于2^64-1已经是 unsigned LL 的最大值了,为了避免溢出,指数应该从当前底数能达到的最大指数开始枚举。

    3.由于一个超级数可能被多次访问到,所以用STL的 set 可以解决重复、离散化的问题,而且还能排序。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 #define ms(a,b) memset((a),(b),sizeof((a)))
    13 using namespace std;
    14 typedef long long LL;
    15 const int INF = 2e9;
    16 const LL LNF = 9e18;
    17 const int mod = 1e9+7;
    18 const int maxn = 1e5+100;
    19 
    20 int vis[100];
    21 void init()
    22 {
    23     int m = sqrt(64+0.5);
    24     for(int i = 2; i<=m; i++) if(!vis[i]) {
    25         for(int j = i*i; j<64; j += i)
    26             vis[j] = 1;
    27     }
    28 }
    29 
    30 typedef unsigned long long ull;
    31 set<ull>s;  //用set完成了排序加去重的功能
    32 int main()
    33 {
    34     init(); //标记在64以为的合数
    35     for(ull i = 2;; i++)    //枚举底数
    36     {
    37         int t = ceil(64*log(2)/log(i)) - 1;
    38         if(t<4) break;
    39         ull x = 1;
    40         for(int j = 1; j<=t; j++)
    41         {
    42             x *= i;
    43             if(vis[j]) s.insert(x);
    44         }
    45     }
    46 
    47     s.insert(1);
    48     set<ull>::iterator it;
    49     for(it = s.begin(); it!=s.end(); it++)
    50         cout<<*it<<endl;
    51 }
    View Code
  • 相关阅读:
    将本地文件夹添加到Git仓库
    flex调用Webservice(一)
    经典的sql
    打印相关
    reporting services订阅
    关于TabIndex
    试题(一)
    试试用手机
    2010.07.13_19:30
    基础知识
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8391584.html
Copyright © 2011-2022 走看看