Codeforces 385C Bear and Prime Numbers
其实不是多值得记录的一道题,通过快速打素数表,再做前缀和的预处理,使查询的复杂度变为O(1)。
但是,我在统计数组中元素出现个数时使用了map,以至于后面做前缀和的累加时,每次都要对map进行查询,以至于TLE。而自己一直没有发现,以为是欧拉筛对于这道题还不够优,于是上网搜题解,发现别人的做法几乎一样,但是却能跑过,挣扎了许久才想起是map的原因。map的内部实现是一颗红黑树,每次查询的复杂度为O(logN),在本来时间就不富裕的情况下,导致了超时。改用数组来统计后,顺利AC。做题时,在空间允许的情况下,还是尽量用数组来做整数间的映射吧,因为这道题纠结了许久,于是做个记录。
附上AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<algorithm>
#include<climits>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef map<int, int> M;
typedef vector<int> V;
typedef queue<int> Q;
const int maxn=10000000+5;
int cnt[maxn];
bool is[maxn];
int prime[maxn/2];
ll sum[maxn];
void init(int mx)
{
int i,j,count=0;
for (i=2;i<=mx;++i)
{
if (!is[i])
{
prime[count++]=i;
}
for (j=0;j<count&&i*prime[j]<=mx;++j)
{
is[i*prime[j]]=true;
if (i%prime[j]==0)
break;
}
}
for (i=2;i<=mx;++i)
{
if (!is[i])
{
for (j=1;j*i<=mx;++j)
{
sum[i]+=cnt[i*j];
}
sum[i]+=sum[i-1];
}
else
sum[i]=sum[i-1];
}
return;
}
int main()
{
int n,t,m,k,i,j;
cin>>n;
for (i=0;i<n;++i)
{
scanf("%d",&t);
cnt[t]++;
}
init(maxn);
cin>>m;
while (m--)
{
int l,r;
scanf("%d%d",&l,&r);
l=min(maxn,l);
r=min(maxn,r);
printf("%d\n",sum[r]-sum[l-1]);
}
return 0;
}
原文地址:https://www.cnblogs.com/orangee/p/8977964.html
时间: 2024-10-12 19:23:48