您的位置:首页 > 其它

DP+埃氏筛法 Codeforces Round #304 (Div. 2) D. Soldier and Number Game

2015-05-26 14:43 507 查看
题目传送门

 /*
题意:b+1,b+2,...,a 所有数的素数个数和
DP+埃氏筛法:dp[i] 记录i的素数个数和,若i是素数,则为1;否则它可以从一个数乘以素数递推过来
最后改为i之前所有素数个数和,那么ans = dp[a] - dp[b];
详细解释:http://blog.csdn.net/catglory/article/details/45932593
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
using namespace std;

typedef long long ll;

const int MAXN = 5e6 + 10;
const int INF = 0x3f3f3f3f;
int prime[MAXN];
bool is_prime[MAXN];
ll dp[MAXN];

int seive(void)
{
for (int i=0; i<=5e6; ++i)    is_prime[i] = true;
is_prime[0] = is_prime[1] = false;
int p = 0;
for (int i=2; i<=5e6; ++i)
{
if (is_prime[i])
{
prime[++p] = i;
for (int j=2*i; j<=5e6; j+=i)    is_prime[j] = false;
}
}

return p;
}

void solve(void)
{
int p = seive ();
for (int i=2; i<=5e6; ++i)
{
if (is_prime[i])    {dp[i] = 1;    continue;}
for (int j=1; j<=p; ++j)
{
if (i % prime[j] == 0)
{
dp[i] = dp[i/prime[j]] + 1;    break;
}
}
}

for (int i=3; i<=5e6; ++i)    dp[i] += dp[i-1];
}

int main(void)        //Codeforces Round #304 (Div. 2) D. Soldier and Number Game
{
solve ();
int t;    scanf ("%d", &t);
while (t--)
{
int a, b;
scanf ("%d%d", &a, &b);
printf ("%I64d\n", dp[a] - dp[b]);
}

return 0;
}

/*
3
3 1
6 3
5000000 4999995
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: