您的位置:首页 > 编程语言 > Go语言

xt 1140 Anti-Goldbach's Conjecture

2012-05-22 03:13 295 查看
哥德巴赫猜想:
任一大于2的偶数,都可表示成两个素数之和。
是世界上最著名的未解问题之一,但是下面的反哥德巴赫猜想:
任一大于11的奇数,都可表示成两个合数之和。
确很容易证明。
定义反哥德巴赫分拆数g(n)表示将大于11的奇数n分解为两个合数之和的方案数。再定义sg(n)=sum({g(i)
| i ≤ n}),即所有不大于n的奇数的反哥德巴赫分拆数之和。你的任务就是快速的计算给定n所对应的sg(n)。
Input
有大约100组测试数据。每组测试数据占一行,包含唯一的一个正整数13 ≤ n ≤ 1000000。输入以EOF结束。
Output
对于输入n,输出对应的sg(n)。
Sample Input
13
14
15
Sample Output
1
1
2

求g[i]只要枚举小于i-2的奇合数(2为偶素数)就可以了

o(n log n)树状数组解法

#include <stdio.h>
#define N 1000001
#define lowbit(i) i&(-i)

__int64 pri
= {0};
__int64 sg
= {0},a
= {0};

void add(__int64 i)
{
for(;i < N; i += lowbit(i))
a[i] ++;
}
__int64 sum(__int64 i)
{
__int64 s= 0;
for(;i > 0; i -= lowbit(i))
s += a[i];
return s;
}
void p()
{
__int64 i,j;
for(i = 2;i <= 1000; ++i)
if(!pri[i])
{
for(j = i;j * i <N;++j)
pri[j*i] = 1;
}
for(i = 9; i < N; i += 2)
{
if(pri[i] && (i&1))
add(i);
}
}
void cal_s()
{
sg[11] = 0;
for(__int64 i = 13; i < N; i += 2)
sg[i] = sum(i - 3);

for(__int64 i = 13; i < N; i+=2)
sg[i] += sg[i-2];
}
int main()
{
p();
cal_s();
__int64 a;
while(scanf("%I64d",&a) != EOF)
{
if((a&1) == 0)
--a;
printf("%I64d\n",sg[a]);
}
return 0;
}


o(n)解法

#include <stdio.h>

#define N 1000001

int pri
= {0},sg
= {0},cnt;

void p()
{
int i,j;
for(i = 2;i <= 1000; ++i)
if(!pri[i])
{
for(j = i;j * i <N;++j)
pri[j*i] = 1;
}
for(i = 9,cnt = 0; i < N; i += 2)
{
if(pri[i]&&(i&1))
pri[cnt++] = i;
}
}
void cal_s()
{
sg[11] = 0;
for(int i = 13,cnt = 1; i < N; i += 2)
{
while(i - pri[cnt] > 2)
++cnt;
sg[i] = cnt;
}
for(int i = 13; i < N; i+=2)
sg[i] += sg[i-2];
}
int main()
{
p();
cal_s();
int a;
while(scanf("%d",&a) != EOF)
{
if((a&1) == 0)
--a;
printf("%d\n",sg[a]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: