F. The Neutral Zone(優化素數篩)

F. The Neutral Zone

time limit per test

5 seconds

memory limit per test

16 megabytes

input

standard input

output

standard output

Notice: unusual memory limit!

After the war, destroyed cities in the neutral zone were restored. And children went back to school.

The war changed the world, as well as education. In those hard days, a new math concept was created.

As we all know, logarithm function can be described as:log(pa11pa22...pa2k)=a1logp1+a2logp2+...+aklogpklog⁡(p1a1p2a2...pka2)=a1log⁡p1+a2log⁡p2+...+aklog⁡pkWhere pa11pa22...pa2kp1a1p2a2...pka2 is the prime factorization of a integer. A problem is that the function uses itself in the definition. That is why it is hard to calculate.

So, the mathematicians from the neutral zone invented this:exlogf(pa11pa22...pa2k)=a1f(p1)+a2f(p2)+...+akf(pk)exlogf(p1a1p2a2...pka2)=a1f(p1)+a2f(p2)+...+akf(pk)

Notice that exlogf(1)exlogf(1) is always equal to 00.

This concept for any function ff was too hard for children. So teachers told them that ff can only be a polynomial of degree no more than 33 in daily uses (i.e., f(x)=Ax3+Bx2+Cx+Df(x)=Ax3+Bx2+Cx+D).

"Class is over! Don't forget to do your homework!" Here it is:n∑i=1exlogf(i)∑i=1nexlogf(i)

Help children to do their homework. Since the value can be very big, you need to find the answer modulo 232232.

Input

The only line contains five integers nn, AA, BB, CC, and DD (1≤n≤3⋅1081≤n≤3⋅108, 0≤A,B,C,D≤1060≤A,B,C,D≤106).

Output

Print the answer modulo 232232.

Examples

input

Copy

12 0 0 1 0

output

Copy

63

input

Copy

4 1 2 3 4

output

Copy

136

普通的歐拉線性篩選素數的方法中需要開出o(n)的5字節數組,使用的數據範圍有限,1e7 就基本封頂啦。但素數與素數之間並不是連續的,因此可以考慮不用連續的枚舉每一個數。除了2,3,相鄰素數都有一個關係:5 7 11 13 17 ...
+2,+4,+2,+4,這樣枚舉下去一定會枚舉到所有結果的。那麼這樣一來就枚舉了原來的n/3,另外開bitset做標記數組這樣就能訪問3e8以內的所有素數。1e8 以內只有6e6 不到的素數。

#include<iostream>
#include<algorithm>
#include<set> 
#include<cstdio>
#include<bitset>
using namespace std;
typedef unsigned ll;
bitset <100000008> bt;
ll n,a,b,c,d;
ll res;
ll cal(ll x)
{
	ll ans = a*x*x*x+b*x*x+c*x+d;
	ll t = n;
	while(t / x) res += ans*(t/=x);
}
int main()
{
	scanf("%u%u%u%u%u",&n,&a,&b,&c,&d);
	cal(2),cal(3);
	for(ll i = 5,j = 2; i <= n; i+=j,j=6-j)
	{
		if(bt[i/3LL]) continue;
		cal(i);	if(i > n/i) continue;
		for(ll k = i*i,v = j; k <= n; k += v*i,v = 6-v) bt[k/3LL] = 1;
	}
	cout << res <<endl;
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章