The Super Powers UVA - 11752

本文介绍了使用C++进行编程竞赛的技巧,包括利用STL库中的set容器进行数据去重,快速幂运算实现高效计算,以及如何通过筛选素数来减少不必要的计算。文章通过具体的代码示例展示了这些技巧的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 通过这道题,学到去重的两种途径:
    1.) stl里的set(集合(有序,不重复)(给予红黑树-一种特殊的二叉搜索树,不可删除(貌似是这么回事)))。
    2.)stl里有个去重函数unique;具体用法如下:

    /**
    Ps:unique(),并不是正真的去重,只是把重复元素移动到序列尾部,真正的去重是ans.earse()
    下面的代码可能有误,没有验证。
    **/
    set<unsigned long long >ans;
    //......压入数据
    sort(ans.begin(),ans.end());
    vector<unsigned long long>::iterator end_unique;
    end_enique=unique(ans.begin(),ans.end());
    ans.erase(end_enique,ans.end());

2.认识到的第二点:自然数根据因子可分解为素数,合数,1.(Ps:自然数>=0)

3.认识到第三点:根据题目要求,满足题目的数据类似与:
t=a^s(a>=2);
t<=2^64-1;
所以我们只需要对应a的最大幂即s的大小即可。(PS: s 为合数,素数打表即可。根据题目要求)
令ss= 2^64-1;
则 s=loga(ss)=ln(ss)/ln(a);
对应的s的最大值 即可求出。
接下来,就是很水的事了(不过我还wa了好多次)。

4.WA代码:

#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ll;
const int maxn =64;

bool vis[maxn];
void get_prime()
{
    memset(vis,0,sizeof(vis));
    int i,j,k;
    for (i=2;i<maxn;i++)
    {
         if(!vis[i])
         for (j=i*i;j<maxn;j+=i)
            vis[j]=1;
    }
}
ll quick_pow(int a,int n)
{
    ll result =1;
     while (n)
     {
         if (n&1)
         result*=a;
         n>>=1;
         a=a*a;
     }
     return result ;
}
// if not prime,vis[i]=1;
int main ()
{
    int  mm=1<<16;
    //cout<<mm<<endl;
     int i,j,k;
     set<ll>a;
     get_prime();
     a.insert(1);
     ll s=quick_pow(2,64)-1;
     for (i=2;i<mm;i++)
     {
        int t=(int)ceil(log(s)/log(i*1.0));
       // cout<<t<<endl;
        //break;
         for (j=4;j<t;j++)
            if(vis[j])
            a.insert(quick_pow(i,j));
     }
     set<ll>::iterator it;
    for (it=a.begin();it!=a.end();it++)
    cout<<*it<<endl;

    return 0;
}

Ps:超过ull的上限。。y一直wa

5.AC代码:

#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ll;
const int maxn =64;

bool vis[maxn];
void get_prime()
{
    memset(vis,0,sizeof(vis));
    int i,j,k;
    for (i=2;i<maxn;i++)
    {
         if(!vis[i])
         for (j=i*i;j<maxn;j+=i)
            vis[j]=1;
    }
}

// 之前一直是包内存
ll quick_pow(ll a,int n)
{
    ll result =1;
     while (n)
     {
         if (n&1)
         result*=a;
         n>>=1;
         a=a*a;
     }
     return result ;
}
// if not prime,vis[i]=1;
int main ()
{
    int  mm=1<<16;
    //cout<<mm<<endl;
     int i,j,k;
     set<ll>a;
     get_prime();
     a.insert(1);
     ll s=quick_pow(2,64)-1;//
     for (i=2;i<mm;i++)
     {
        int t=(int)ceil(log(s)/log(i*1.0));

         for (j=4;j<t;j++)
            if(vis[j])
            a.insert(quick_pow(i,j));
     }
     set<ll>::iterator it;
    for (it=a.begin();it!=a.end();it++)
    cout<<*it<<endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值