Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<iostream>
- #include<cmath>
- #include<memory.h>
- const int threads_num=4;
- const int SQRT_MAXN = 33000;
- const int S = 100000; //размер блока
- bool nprime[SQRT_MAXN], bl[threads_num][S];
- int primes[SQRT_MAXN], cnt;
- long long ans[threads_num];
- long long pre[]={0, 1906816620981654LL, 7357074544482779LL, 16217881619242062LL, 28422918403819825LL};
- int n;
- int startBlock, endBlock;
- int nstart, nend;
- void* exec(void *tid)
- {
- long id=(long)tid;
- int bcnt=(endBlock-startBlock+1)/threads_num; // количество блоков на поток
- int bend=(id==threads_num-1)? (endBlock+1) : (id+1)*bcnt+startBlock; //последний обрабатывает остаток
- for (int k=id*bcnt+startBlock; k<bend; ++k)
- {
- memset (bl[id], 0, sizeof(bool)*S);
- int tstart = k * S; //число с которого начинается блок
- for (int i=0; i<cnt; ++i)
- {
- int start_idx = (tstart + primes[i] - 1) / primes[i], j;
- j = start_idx>1 ? start_idx : 2;
- j = j * primes[i] - tstart;
- for (; j<S; j+=primes[i])
- bl[id][j] = true;
- }
- if (k == 0)
- bl[id][0] = bl[id][1] = true;
- for (int i=std::max(0, nstart-tstart); i<S && tstart+i<=nend; ++i)
- if (!bl[id][i])
- ans[id]+=tstart+i;
- }
- return NULL;
- }
- long long calc(int start, int end)
- {
- long long res=0;
- startBlock = start/S;
- endBlock=end/S;
- nstart=start; nend=end;
- int nsqrt = (int) sqrt (end + .0);
- primes[cnt++]=2;
- for (int i=3; i<=nsqrt; i+=2)
- if (!nprime[i]) {
- primes[cnt++] = i;
- for (int j=i*i; j<=nsqrt; j+=i)
- nprime[j] = true;
- }
- pthread_t threads[threads_num];
- for(int i=0; i<threads_num; ++i)
- pthread_create(threads + i, NULL, exec, (void*)(i));
- for(int i = 0; i < threads_num; i++)
- pthread_join(threads[i], NULL);
- for(int i=0; i<threads_num; ++i)
- res+=ans[i];
- return res;
- }
- int main() {
- long long res=0;
- int n;
- std::cin >> n;
- int i=(n-1)/(1<<28);
- int start=i*(1<<28)+1;
- int end=(i+1)*(1<<28);
- if(n-start < end-n)
- res=pre[i] + calc(start+1, n);
- else
- res=pre[i+1]-calc(n+1, end);
- std::cout << res;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement