The slow part is probably your factoring. If you are iterating up to the square root of i and using the totient function then I would think that would be fast enough.
You could always try to use a faster factoring method.
Moderator: Board moderators
Now you're thirdObserver wrote:I'm currently ranked #2 for this task. But I have no idea how 0.00.002 can be achieved.... Faster I/O?

Krzysztof Duleba wrote:Now you're third
for (i=3;i<=223;i+=2) if (!fac[i]) for (s=i*i;s<=50000;s+=i<<1) fac[s]=i;for(i=1;i<50001;i++)
nrp[i]=i;
for(i=2;i<50001;i++)
if(nrp[i]==i)
{
nrp[i]--;
for(j=i<<1;j<=50000;j+=i)
nrp[j]=nrp[j]*(i-1)/i;
}
last = ans[1] = 1;
for(i=2;i<=50000;i++)
last = ans[i] = last + (nrp[i]<<1); // variable last is used instead of ans[i-1] just to save a few memory accesses
sandy007smarty wrote:@sclo:
1. Is their some faster sieve algo? Can you provide some links?
2. Calculating result[i]+=result[i-1]+result[i]<<1 and just printing result[n] seems similar to what you suggest. I can't see what computational advantages your method has.
Below is my code for calculating totient using sieve:-
- Code: Select all
for(i=1;i<50001;i++)
nrp[i]=i;
for(i=2;i<50001;i++)
if(nrp[i]==i)
{
nrp[i]--;
for(j=i<<1;j<=50000;j+=i)
nrp[j]=nrp[j]*(i-1)/i;
}
And this is my code for calculating result:-
- Code: Select all
last = ans[1] = 1;
for(i=2;i<=50000;i++)
last = ans[i] = last + (nrp[i]<<1); // variable last is used instead of ans[i-1] just to save a few memory accesses
I would appreciate if you could suggest some ways to improve above functions.
const int MAXN = 50005;
bool isPrime[MAXN+5];
int phi[MAXN],farey[MAXN];
void init()
{
// generate prime numbers
memset(isPrime,true,sizeof(isPrime));
isPrime[0] = isPrime[1] = false;
for(int i = 2; i*i <= MAXN; i ++)
if(isPrime[i])
for(int j = i; j*i <= MAXN; j ++)
isPrime[i*j] = false;
// because phi(i) = i*(1-p1/p1)*...*(1-pk/pk), you can generate the phi[] array similar to the way we generate prime numbers
for(int i = 1; i <= MAXN; i ++) phi[i] = i;
for(int i = 2; i <= MAXN; i ++)
if(isPrime[i])
for(int j = i; j <= MAXN; j += i)
phi[j] = phi[j]/i * (i-1);
// sum up phi[i] to farey[i]. obiously, the answer for a given N would be (2*farey[N]-1).
farey[1] = 1;
for(int i = 2; i <= MAXN; i ++)
farey[i] = farey[i-1] + phi[i];
}
Users browsing this forum: No registered users and 1 guest