Codeforces Round #502 (Div. 1 + Div. 2)F. The Neutral Zone(分段筛)

版权声明:转载需要注明哦QwQ,地址:http://blog.csdn.net/effervescence。 https://blog.csdn.net/Effervescence/article/details/81531924

题意

  我们知道, l o g ( p 1 a 1 p 2 a 2 p 3 a 3 . . . ) = a 1 l o g p 1 + a 2 l o g p 2 + . . . (其中p为质数)
   p 1 a 1 p 2 a 2 p 3 a 3 . . .
  现在我们定义 e x l o g ( p 1 a 1 p 2 a 2 p 3 a 3 . . . ) = a 1 f ( p 1 ) + a 2 f ( p 2 ) + . . .
  其中 f ( x ) 为一个次数不超过3次的多项式,即 f ( x ) = A x 3 + B x 2 + C x + D
  注意到exlog(1)永远等于0。
  现在给出 n , A , B , C , D ,求 i = 1 n e x l o g ( i )
  注意Memory Limit为16M

分析

  首先我们考虑,对于一个质数,他跟其他的质数是没有联系的。所以我们可以考虑每个质数 p 对答案的贡献。他的 k 次即 k f ( p ) 对答案的贡献为 n p k 次。那么我们最主要的就是如何筛素数了。直接筛肯定筛不出来,只能通过埃氏筛区间筛出来,因为埃氏筛可以只记录一个划掉的数的表。这样我们就可以做完这道题了。

Code

#pragma GCC optimize(3)
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
int n,cnt,prime[200005],lim,tmp,l,r;
unsigned A,B,C,D,res;
bool b[2000005];
inline void sieve() {
    for(int i=2;i<=30000;i++) {
        if(!b[i]) {
            prime[++cnt]=i;
            for(int j=i+i;j<=30000;j+=i)
                b[j]=1;
        }
    }
    lim=3e8,l=2,r=tmp=2000000;
}
inline void Sieve() {
    memset(b,0,sizeof(b));
    for(int i=1;i<=cnt;i++) {
        int x=prime[i];
        for(int j=max(2,l/x+!!(l%x))*x;j<=r;j+=x)
            b[j-l]=1;
    }
}
inline unsigned getans(unsigned x) {
    unsigned val=A*x*x*x+B*x*x+C*x+D,ans=0;
    long long now=x;
    while(now<=n)
        ans+=val*(n/now),now*=x;
    return ans;
}
inline void solve() {
    for(int i=l;i<=r;i++)
        if(!b[i-l])
            res+=getans(i);
}
inline void work() {
    while(l<=n) {
        Sieve();
        solve();
        l=r+1,r=l+tmp-1;
    }
}
int main() {
    read(n),read(A),read(B),read(C),read(D);
    sieve();
    work();
    printf("%u\n",res);
}

猜你喜欢

转载自blog.csdn.net/Effervescence/article/details/81531924