链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1140
看到题目首先就想到打表,打表这个过程是没错,但是,打表后该怎么做了,这题目有点蛋疼,输出的时候
要输出的它前面的数包括他自己的总和,首先朴素的枚举他前面的所有答案,然后加起来,肯定会超时的。
这题可以打奇合数的表,可以打素数的表,可以找规律,每次方法对应不同的算法,我是打奇合数的表
因为每有一个奇合数,这个奇数,就对应了一个方案,因为在此题目中的要满足奇数=奇合数+偶合数,
顺带一提而且这个奇数A,只有A-4之前的奇合数才能满足要求,比如17的前面奇合数有915而15不满足,因为
没有一个和15配对的合数,所以只要算A-4之前的奇合数就行
打完奇合数表就完成第一步了,然后就是怎样算出它前面的数的方案数的总和,我这里用了一个数组
bx[i]表示i这个数之前有多少个奇合数,ax[i]是打出的奇合数的表,满足要求的是1,其他为0
for(len=0,i=9;i<=1000000;i++)
{
if(ax[i])
len++;
bx[i+4]=len;
}
这里加4不明白 请参考前面红字部分说的
然后后面复杂度就减少了,还要用64为防溢出.
AC代码如下:
看到题目首先就想到打表,打表这个过程是没错,但是,打表后该怎么做了,这题目有点蛋疼,输出的时候
要输出的它前面的数包括他自己的总和,首先朴素的枚举他前面的所有答案,然后加起来,肯定会超时的。
这题可以打奇合数的表,可以打素数的表,可以找规律,每次方法对应不同的算法,我是打奇合数的表
因为每有一个奇合数,这个奇数,就对应了一个方案,因为在此题目中的要满足奇数=奇合数+偶合数,
顺带一提而且这个奇数A,只有A-4之前的奇合数才能满足要求,比如17的前面奇合数有915而15不满足,因为
没有一个和15配对的合数,所以只要算A-4之前的奇合数就行
打完奇合数表就完成第一步了,然后就是怎样算出它前面的数的方案数的总和,我这里用了一个数组
bx[i]表示i这个数之前有多少个奇合数,ax[i]是打出的奇合数的表,满足要求的是1,其他为0
for(len=0,i=9;i<=1000000;i++)
这里加4不明白 请参考前面红字部分说的
然后后面复杂度就减少了,还要用64为防溢出.
AC代码如下:
#include <stdio.h>
#include <math.h>
#include <string.h>
long long ax[1000005]={0};
long long bx[1000005]={0};
long long cx[1000005]={0};
int main()
{
long long i,j,k,m,len=0,a;
for(i=2;i<=500000;i++)
{
for(j=i+i;j<=1000000;j+=i)
{
if(j%2==1)
ax[j]=1;
}
}
for(i=9;i<=1000000;i++)
{
if(ax[i])
len++;
bx[i+4]=len;
}
while(scanf("%I64d",&a)!=EOF)
{
long long sum=0;
for(i=13;i<=a;i+=2)
sum+=bx[i];
printf("%I64d\n",sum);
}
}