- 注册时间
- 2007-12-27
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 49019
- 在线时间
- 小时
|
上面的公式有个问题,没有考虑到对于越大的数,对应的计算量越大。由于我们实际计算过程都是一个超大整数乘上一个小于\(10^{10}\)的整数
所以实际上每次乘法本身就是O(n)的,由此总体复杂度可以表示为
\(\sum_{x=10^9}^{10^{10}-1}\frac{x\ln(0.1)}{\ln(10^{-10}x)}\approx 10^{20}\ln(0.1)(Ei(2\ln(1-10^{-10}))-Ei(2\ln(0.1)))\).
而计算过程中,如果我们从\(10^9\)已经计算到\(10^{10}-10^7\),那么我们就可以估算出计算过程已经占了整体计算量的
\(\frac{Ei(2\ln(0.999))-Ei(2\ln(0.1)))}{Ei(2\ln(1-10^{-10}))-Ei(2\ln(0.1)))} \approx 0.2088\)
通过这种方法可以估算出完成整个计算大概需要8K CPU日左右, 对于现代多核处理器也不是不能完成,就是时间略微长了点,如果能够优化一下会更好。
- #include <math.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- #define SN 501
- #define MP 100000000
- #define MOD 10000000000L
- #define HMOD 100000
- char dc[HMOD][10];
- void initdc()
- {
- int i;
- for(i=0;i<HMOD;i++){
- int j;
- int x=i;
- for(j=0;j<5;j++){
- dc[i][x%10]++;
- x/=10;
- }
- }
- }
- void get_count(long v[],int length, int count[10])
- {
- int i;
- for(i=0;i<10;i++)count[i]=0;
- for(i=0;i<length;i++){
- int x=v[i]%HMOD;
- int y=v[i]/HMOD;
- int j;
- for(j=0;j<10;j++){
- count[j]+=dc[x][j]+dc[y][j];
- }
- }
- }
- bool mulby(long v[], int length, long m)
- {
- int i;
- long carry=0L;
- for(i=0;i<length;i++){
- __int128_t prod = (__int128_t)v[i]*m+carry;
- v[i]=prod%MOD;
- carry=prod/MOD;
- }
- v[length]=carry;
- return carry>=(MOD/10);
- }
- int main()
- {
- double sv=pow(0.1,1.0/SN)*MOD;
- long is = (long)ceil(sv);
- initdc();
- time_t start=time(NULL);
- #pragma omp parallel
- {
- long *data = (long *)malloc((MP+1)*sizeof(long));
- #pragma omp for schedule(dynamic)
- for(long i=is;i<MOD;i++){
- int count[10];
- data[0]=i;
- int j;
- for(j=2;j<=MP;j++){
- if(!mulby(data,j-1,i))break;
- if(j<SN)continue;
- get_count(data,j,count);
- int k;
- for(k=0;k<10;k++)if(count[k]!=j)break;
- if(k==10){
- #pragma omp critical
- {
- printf("%ld^%d\n",i,j);
- fflush(stdout);
- }
- }
- }
- #pragma omp critical
- if(i%1000000==0)
- {
- time_t now=time(NULL);
- fprintf(stderr,"%ld cost %ld\n",i,now-start);
- fflush(stderr);
- }
- }
- }
- printf("done!\n");
- return 0;
- }
复制代码
|
|