通过这道题,学到去重的两种途径:
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;
}