这题我背最大的锅,这种题目显然是考虑所有分母的
,今年的校赛我还出过一道这样的题,然而比赛时我竟然是找规律凭第一感觉判断的,真的tcl
对于第 个数,我们需要的只是考虑他的前缀所有分母的 ,而 的本质就是取同类质因子的 ,打表或者手写前几十个数,不难发现这样的规律:只有含单个质因子的数才会贡献一次答案,而贡献的就是它的唯一质因子。那么对于这样的数我们只需素筛,然后找每种质因子在最大范围所有的次幂数并打上标记,然后从前向后更新答案
赛后补题多写了一个 循环就 了,多开一个数组就 了,实际上我们只需要在欧拉筛的过程中计算答案
更让我没想到的是,比赛时一开始是直接对 取模,然后发现根据位运算的性质可以优化为 ,实际上 不就是 的最大范围吗,根据无符号整型数自然溢出的性质,直接计算即可,妙啊
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const double dinf=1e300;
const ll INF=1e18;
const ll Mod=(1LL<<32)-1;
const int maxn=8e7+10;
const int maxm=5e6+10;
int cnt,n;
int f[maxn],prime[maxm];
bool isprime[maxn];
unsigned int a,b;
void eular(int n){
for(int i=2;i<=n;i++){
if(!isprime[i]){
prime[cnt++]=i;
ll x=i;
while(x<=n){
f[x]=i;
x=x*i;
}
}
if(f[i]) a=a*f[i]+b;
for(int j=0;j<cnt && i*prime[j]<=n;j++){
isprime[i*prime[j]]=1;
if (i%prime[j]==0) break;
}
}
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
scanf("%d%u%u",&n,&a,&b);
eular(n);
printf("%u\n",a);
return 0;
}