zoukankan      html  css  js  c++  java
  • CodeForces

    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⁡pk

    Where 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:

    i=1nexlogf(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 (1n31081≤n≤3⋅108, 0A,B,C,D1060≤A,B,C,D≤106).

    Output

    Print the answer modulo 232232.

    Examples

    Input
    12 0 0 1 0
    Output
    63
    Input
    4 1 2 3 4
    Output
    136

    题意:给定函数Fx=A*x^3+B*x^2+C*x+D; 而函数Fx=Fa1+Fa2+...,当且仅当x=p1^a1+p2^a2+...

    思路:很显然我们是算关于每个素数p的函数,Fp。然后乘其贡献次数nump。 Fp可以算,nump=N/p+N/p/p+N/p/p/p+....

    N以内的素数个数约有N/lnN个,所以算每个素数的nump复杂度为O(NlglgN),可以搞。那么现在的关键就是在16M,5s的空间和时间里筛出3e8的素数。

    显然压空间可以用bitset,bitset存1e8的空间只需要12.5M。再利用2,3以外的素数==6x+-1,压缩一下就搞定了。 以下代码筛3e8的素数只需要250ms。

    void prime()
    {
        add(2); add(3); //单独考虑 
        for(UI i=5,d=2;i<=N;i+=d,d=6-d) {
           if(!p[i/3]){
              add(i); if(i>N/i) continue;
              for(UI j=i*i,v=d;j<=N;j+=i*v,v=6-v) p[j/3] = 1;
           } 
        }
    }

    所以,搞定! 当然,也可以用区间筛法,一段一段的搞定。

    #include<bits/stdc++.h> 
    using namespace std;
    typedef unsigned int UI;
    UI ans,N,A,B,C,D;
    bitset<100000001>p;
    inline void add(UI x) {
        UI f=A*x*x*x+B*x*x+C*x+D;
        for(UI t=N;t;t/=x) ans+=t/x*f;
    }
    void prime()
    {
        add(2); add(3); //单独考虑 
        for(UI i=5,d=2;i<=N;i+=d,d=6-d) {
           if(!p[i/3]){
              add(i); if(i>N/i) continue;
              for(UI j=i*i,v=d;j<=N;j+=i*v,v=6-v) p[j/3] = 1;
           } 
        }
    }
    int main() {
       scanf("%u%u%u%u%u",&N,&A,&B,&C,&D);
       prime();
       printf("%u
    ", ans);
       return 0;
    }
  • 相关阅读:
    hdoj2159【二位费用背包】
    POJ2367【拓扑排序】
    POJ2371【水题】
    POJ2369【循环节】
    POJ2370【水题】
    POJ2365【几何】
    POJ2366【二分】
    POJ1276【多重背包】
    瞎说一波3种基本背包问题【希望巨巨们指出错误】
    Codeforces 550B 【暴力】
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9478139.html
Copyright © 2011-2022 走看看