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

本文介绍了一种特殊定义的日志函数exlog,并探讨了如何使用质数筛法来高效计算从1到n的所有整数的exlog值之和。此算法涉及质数分解、埃氏筛法及多项式计算。

题意

  我们知道,log(p1a1p2a2p3a3...)=a1logp1+a2logp2+...log(p1a1p2a2p3a3...)=a1logp1+a2logp2+...(其中p为质数)
  p1a1p2a2p3a3...p1a1p2a2p3a3...为一个数的质因数分解的表示形式。
  现在我们定义exlog(p1a1p2a2p3a3...)=a1f(p1)+a2f(p2)+...exlog(p1a1p2a2p3a3...)=a1f(p1)+a2f(p2)+...
  其中f(x)f(x)为一个次数不超过3次的多项式,即f(x)=Ax3+Bx2+Cx+Df(x)=Ax3+Bx2+Cx+D
  注意到exlog(1)永远等于0。
  现在给出n,A,B,C,Dn,A,B,C,D,求i=1nexlog(i)∑i=1nexlog(i)
  注意Memory Limit为16M

分析

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

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);
}
Codeforces Round 1036 是一场同时面向 Div.1Div.2 参赛者的比赛,通常这类比赛会包含多个具有挑战性的编程题目,涵盖算、数据结构、数学等多个领域。比赛的题解和题目信息可以帮助参赛者回顾解题思路,提升编程能力。 ### 比赛基本信息 - **比赛名称**:Codeforces Round #1036 (Div. 1 and Div. 2) - **比赛时间**:具体时间为 UTC+X(根据实际举办日期和时间表) - **比赛链接**:[Codeforces 官方页面](https://codeforces.com/contest/1343) - **题解发布位置**:通常在比赛结束后不久,官方或社区成员会在 Codeforces 博客、GitHub 或其他技术平台上发布题解。 ### 题目类型与难度分布 该轮比赛通常包括 5 到 7 道题目,难度从简单实现到复杂算不等。例如: - **A题**:通常是简单的模拟或数学问题。 - **B题**:可能涉及字符串处理或基础贪心策略。 - **C题**:中等难度,可能需要掌握基本的数据结构如数组、排序等。 - **D题及以后**:较高难度,可能涉及图论、动态规划、数论等高级算### 参赛情况与亮点 - **参与人数**:通常超过 10,000 名选手参加。 - **热门话题**:比赛中某些题目可能会引发广泛讨论,尤其是那些需要用到巧妙构造或优化技巧的问题。 - **知名选手表现**:顶尖选手如 tourist、Um_nik 等通常会以极快的速度完成所有题目,并占据排行榜前列。 ### 示例代码片段 以下是一个典型的 Codeforces 题目解示例,适用于某道中等难度题目: ```cpp #include <bits/stdc++.h> using namespace std; int main() { int t; cin >> t; while(t--) { long long l, r; cin >> l >> r; // 假设 e 是一个预处理好的符合条件的数组 // 使用二分查找来统计区间 [l, r] 内的有效数字个数 long long ans = upper_bound(e.begin(), e.end(), r) - lower_bound(e.begin(), e.end(), l); cout << ans << endl; } return 0; } ``` ### 题解资源推荐 - **Codeforces 官方博客**:通常会有详细的题解和作者说明。 - **GitHub 仓库**:许多参赛者会将自己的解上传至 GitHub,便于他人学习。 - **知乎专栏 / CSDN / 博客园**:中文社区中也常有高质量的赛后总结与分析文章。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值