写新题然后艹翻标程的感觉真是舒爽啊...
这题就是个dfs。。。先预处理出sqrt(n)范围内的素数,然后dfs构造合法的数就行了。
直接暴搜会TLE,需要剪一剪枝,不需要跑到最后一层再计算答案,边构造边更新答案,发现下一层无法出现新答案直接退出就行了
效率大概O(答案个数)
#6222也就是这题加强版需要高精度,出题人直接用python了= = 欺负C++高精度得手写...
而且这种写法是过不了的QAQ,加强版就不是很会了
#include<bits/stdc++.h> #define ull unsigned long long using namespace std; const int maxn=500010; ull n,cnt,ans; int p; ull prime[maxn]; bool v[maxn]; void read(ull &k) { int f=1;k=0;char c=getchar(); while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar(); k*=f; } void dfs(int dep,ull sum) { if(dep==p)return; if(sum*prime[dep+1]*prime[dep+1]<=n)dfs(dep+1,sum); ull now=prime[dep]; for(int i=2;;i++) { now*=prime[dep]; if(sum*now>n)return; dfs(dep+1,sum*now); cnt++;ans+=sum*now; } } int main() { read(n);int m=(int)sqrt(n);v[1]=1; for(int i=2;i*i<=m;i++) if(!v[i])for(int j=i<<1;j<=m;j+=i)v[j]=1; for(int i=2;i<=m;i++)if(!v[i])prime[p++]=i; cnt=ans=1;dfs(0,1); printf("%llu %llu",cnt,ans); return 0; }